Skip to content

Commit 8b60050

Browse files
committed
Refactor Module. Add support for dependency and collection shims
1 parent 33f6d11 commit 8b60050

File tree

7 files changed

+641
-133
lines changed

7 files changed

+641
-133
lines changed

lib/Module.js renamed to lib/graph/Module.js

Lines changed: 90 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ const {promisify} = require("util");
44
const readFile = promisify(fs.readFile);
55
const jsyaml = require("js-yaml");
66
const resourceFactory = require("@ui5/fs").resourceFactory;
7-
const Project = require("./specifications/Project");
8-
const Extension = require("./specifications/Extension");
9-
const Configuration = require("./specifications/Configuration");
10-
const {validate} = require("./validation/validator");
7+
const Project = require("../specifications/Project");
8+
const Extension = require("../specifications/Extension");
9+
const Configuration = require("../specifications/Configuration");
10+
const {validate} = require("../validation/validator");
1111

12-
const log = require("@ui5/logger").getLogger("Module");
12+
const log = require("@ui5/logger").getLogger("graph:Module");
1313

1414
const defaultConfigPath = "ui5.yaml";
1515

@@ -26,12 +26,12 @@ class Module {
2626
* @param {string} [parameters.configPath=ui5.yaml]
2727
* Either a path relative to `modulePath` which will be resolved by @ui5/fs (default),
2828
* or an absolute File System path to the project configuration file.
29-
* @param {object} [parameters.configuration]
30-
* Configuration object to use. If supplied, no ui5.yaml will be read
29+
* @param {object|object[]} [parameters.configuration]
30+
* Configuration object or array of objects to use. If supplied, no ui5.yaml will be read
3131
* @param {@ui5/project.graph.ShimCollection} [parameters.shimCollection]
3232
* Collection of shims that might be relevant for this module
3333
*/
34-
constructor({id, version, modulePath, configPath = defaultConfigPath, configuration, shimCollection}) {
34+
constructor({id, version, modulePath, configPath = defaultConfigPath, configuration = [], shimCollection}) {
3535
if (!id) {
3636
throw new Error(`Could not create Module: Missing or empty parameter 'id'`);
3737
}
@@ -47,7 +47,11 @@ class Module {
4747
this._modulePath = modulePath;
4848
this._configPath = configPath;
4949
this._dependencies = {};
50-
this._suppliedConfig = configuration;
50+
51+
if (!Array.isArray(configuration)) {
52+
configuration = [configuration];
53+
}
54+
this._suppliedConfigs = configuration;
5155

5256
if (shimCollection) {
5357
// Retrieve and clone shims in constructor
@@ -80,61 +84,74 @@ class Module {
8084
return this._modulePath;
8185
}
8286

83-
getDependencies() {
84-
return [];
87+
async getSpecifications() {
88+
if (this._pGetSpecifications) {
89+
return this._pGetSpecifications;
90+
}
91+
92+
return this._pGetSpecifications = this._getSpecifications();
8593
}
8694

87-
async getProject() {
88-
const configs = await this.getConfigurations();
89-
// getConfigurations promises us to return none or exactly one project configuration
90-
const projectConfig = configs.find((config) => {
91-
return config.getKind() === "project";
92-
});
95+
async _getSpecifications() {
96+
const configs = await this._getConfigurations();
9397

94-
if (projectConfig) {
95-
return new Project({
96-
id: this.getId(),
97-
version: this.getVersion(),
98-
modulePath: this.getPath(),
99-
configuration: projectConfig
100-
});
101-
}
102-
}
98+
let project;
99+
const extensions = [];
100+
configs.forEach((configuration) => {
101+
const kind = configuration.getKind();
103102

104-
async getExtensions() {
105-
const configs = await this.getConfigurations();
106-
const extensionConfigs = configs.filter((config) => {
107-
return config.getKind() === "extension";
108-
});
109-
return extensionConfigs.map((config) => {
110-
return new Extension({
111-
id: this.getId(),
112-
version: this.getVersion(),
113-
modulePath: this.getPath(),
114-
configuration: config
115-
});
103+
switch (kind) {
104+
case "project":
105+
if (project) {
106+
throw new Error(
107+
`Invalid configuration for module ${this.getId()}: Per module there ` +
108+
`must be no more than one configuration of kind 'project'`);
109+
}
110+
log.verbose(`Module ${this.getId()} contains project ${configuration.getName()}`);
111+
project = new Project({
112+
id: this.getId(),
113+
version: this.getVersion(),
114+
modulePath: this.getPath(),
115+
configuration
116+
});
117+
break;
118+
case "extension":
119+
log.verbose(`Module ${this.getId()} contains extension ${configuration.getName()}`);
120+
extensions.push(new Extension({
121+
id: this.getId(),
122+
version: this.getVersion(),
123+
modulePath: this.getPath(),
124+
configuration
125+
}));
126+
break;
127+
default:
128+
throw new Error(
129+
`Encountered unexpected specification configuration of kind ${kind} ` +
130+
`Supported kinds are 'project' and 'extension'`);
131+
}
116132
});
133+
134+
return {
135+
project,
136+
extensions
137+
};
117138
}
118139

119140
/**
120141
* Configuration
121142
*/
122-
async getConfigurations() {
123-
if (this._pGetConfigurations) {
124-
return this._pGetConfigurations;
125-
}
126-
127-
return this._pGetConfigurations = this._getConfigurations();
128-
}
129-
130143
async _getConfigurations() {
131144
let configurations;
132-
if (this._suppliedConfig) {
133-
configurations = [await this._createConfigurationInstance(this._suppliedConfig)];
134-
} else {
135-
configurations = await this._loadProjectConfiguration();
145+
146+
configurations = await this._getSuppliedConfigurations();
147+
148+
if (!configurations || !configurations.length) {
149+
configurations = await this._getYamlConfigurations();
136150
}
137-
return configurations;
151+
if (!configurations || !configurations.length) {
152+
configurations = await this._getShimConfigurations();
153+
}
154+
return configurations || [];
138155
}
139156

140157
async _createConfigurationInstance(config) {
@@ -146,7 +163,7 @@ class Module {
146163
return new Configuration(config);
147164
}
148165

149-
async _createProjectConfigurationFromShim() {
166+
async _createConfigurationFromShim() {
150167
const config = this._applyShims();
151168
if (config) {
152169
this._normalizeConfig(config);
@@ -166,16 +183,30 @@ class Module {
166183
return config;
167184
}
168185

169-
async _loadProjectConfiguration() {
186+
async _getSuppliedConfigurations() {
187+
if (this._suppliedConfigs.length) {
188+
log.verbose(`Configuration for module ${this.getId()} has been supplied directly`);
189+
return await Promise.all(this._suppliedConfigs.map(async (config) => {
190+
return this._createConfigurationInstance(config);
191+
}));
192+
}
193+
}
194+
195+
async _getShimConfigurations() {
196+
// No project configuration found
197+
// => Try to create one from shims
198+
const shimConfiguration = await this._createConfigurationFromShim();
199+
if (shimConfiguration) {
200+
log.verbose(`Created configuration from shim extensions for module ${this.getId()}`);
201+
return [shimConfiguration];
202+
}
203+
}
204+
205+
async _getYamlConfigurations() {
170206
const configs = await this._readConfigFile();
171207

172208
if (!configs || !configs.length) {
173-
// No project configuration found
174-
// => Try to create one from shims
175-
const shimConfiguration = await this._createProjectConfigurationFromShim();
176-
if (shimConfiguration) {
177-
return [shimConfiguration];
178-
}
209+
log.verbose(`Could not find a configuration file for module ${this.getId()}`);
179210
return [];
180211
}
181212

@@ -209,13 +240,6 @@ class Module {
209240
const configurations = [];
210241
if (projectConfigs.length) {
211242
configurations.push(await this._createConfigurationInstance(projectConfigs[0]));
212-
} else {
213-
// No project configuration found
214-
// => Try to create one from shims
215-
const shimConfiguration = await this._createProjectConfigurationFromShim();
216-
if (shimConfiguration) {
217-
configurations.push(shimConfiguration);
218-
}
219243
}
220244

221245
await Promise.all(extensionConfigs.map(async (config) => {

lib/graph/ProjectGraph.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ class ProjectGraph {
8181
}
8282
}
8383

84+
getDependencies(projectName) {
85+
return Object.keys(this._adjList[projectName]);
86+
}
8487

8588
/**
8689
* Callback for graph traversal operations
@@ -147,7 +150,7 @@ class ProjectGraph {
147150

148151
return visited[projectName] = (async () => {
149152
const newPredecessors = [...predecessors, projectName];
150-
const dependencies = Object.keys(this._adjList[projectName]);
153+
const dependencies = this.getDependencies(projectName);
151154

152155
queue.push({
153156
projectNames: dependencies,
@@ -194,7 +197,7 @@ class ProjectGraph {
194197
}
195198
return visited[projectName] = (async () => {
196199
const newPredecessors = [...predecessors, projectName];
197-
const dependencies = Object.keys(this._adjList[projectName]);
200+
const dependencies = this.getDependencies(projectName);
198201
await Promise.all(dependencies.map((depName) => {
199202
return this._traverseDepthFirst(depName, visited, newPredecessors, callback);
200203
}));

lib/graph/ShimCollection.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ class ShimCollection {
4040
return this._configShims[moduleId];
4141
}
4242

43-
getDependencyShims(moduleId) {
44-
return this._dependencyShims[moduleId];
43+
getAllDependencyShims() {
44+
return this._dependencyShims;
4545
}
4646

4747
getCollectionShims(moduleId) {

0 commit comments

Comments
 (0)