Skip to content

Commit f4e3f6d

Browse files
committed
Add all missing types and adopt most tests
1 parent 3cdb4a2 commit f4e3f6d

File tree

30 files changed

+1313
-332
lines changed

30 files changed

+1313
-332
lines changed

lib/graph/Module.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ 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 Specification = require("../Specification");
7+
const Specification = require("../specifications/Specification");
88
const {validate} = require("../validation/validator");
99

1010
const log = require("@ui5/logger").getLogger("graph:Module");

lib/graph/ShimCollection.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@ class ShimCollection {
2323
const name = shimExtension.getName();
2424
log.verbose(`Adding new shim ${name}...`);
2525
// TODO: Move this into a dedicated ShimConfiguration class?
26-
const config = shimExtension.getConfigurationObject();
27-
const {configurations, dependencies, collections} = config.shims;
26+
const {configurations, dependencies, collections} = shimExtension.getShimConfiguration();
2827
if (configurations) {
2928
addToMap(name, configurations, this._projectConfigShims);
3029
}
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
const {promisify} = require("util");
2+
const Project = require("./Project");
3+
4+
/*
5+
* Private configuration class for use in Module and specifications
6+
*/
7+
8+
class ComponentProject extends Project {
9+
constructor(parameters) {
10+
super(parameters);
11+
if (new.target === ComponentProject) {
12+
throw new TypeError("Class 'ComponentProject' is abstract. Please use one of the 'types' subclasses");
13+
}
14+
15+
this._pPom = null;
16+
17+
this._namespace = null;
18+
}
19+
20+
/* === Attributes === */
21+
/**
22+
* @public
23+
*/
24+
getNamespace() {
25+
return this._namespace;
26+
}
27+
28+
/**
29+
* @public
30+
*/
31+
getCopyright() {
32+
return this._config.metadata.copyright;
33+
}
34+
35+
/**
36+
* @public
37+
*/
38+
getComponentPreloadPaths() {
39+
return this._config.builder && this._config.builder.componentPreload &&
40+
this._config.builder.componentPreload.paths || [];
41+
}
42+
43+
/**
44+
* @public
45+
*/
46+
getComponentPreloadNamespaces() {
47+
return this._config.builder && this._config.builder.componentPreload &&
48+
this._config.builder.componentPreload.namespaces || [];
49+
}
50+
51+
getJsdocExcludes() {
52+
return this._config.builder && this._config.builder.jsdoc && this._config.builder.jsdoc.excludes || [];
53+
}
54+
55+
/**
56+
* @public
57+
*/
58+
getBundles() {
59+
return this._config.builder && this._config.builder.bundles || [];
60+
}
61+
62+
/* === Internals === */
63+
/**
64+
* @private
65+
* @param {object} config Configuration object
66+
*/
67+
async _parseConfiguration(config) {
68+
await super._parseConfiguration(config);
69+
70+
this._namespace = await this._getNamespace();
71+
}
72+
73+
async _getNamespace() {
74+
throw new Error(`_getNamespace must be implemented by subclass ${this.constructor.name}`);
75+
}
76+
77+
/* === Helper === */
78+
/**
79+
* Checks whether a given string contains a maven placeholder.
80+
* E.g. <code>${appId}</code>.
81+
*
82+
* @param {string} value String to check
83+
* @returns {boolean} True if given string contains a maven placeholder
84+
*/
85+
_hasMavenPlaceholder(value) {
86+
return !!value.match(/^\$\{(.*)\}$/);
87+
}
88+
89+
/**
90+
* Resolves a maven placeholder in a given string using the projects pom.xml
91+
*
92+
* @param {string} value String containing a maven placeholder
93+
* @returns {Promise<string>} Resolved string
94+
*/
95+
async _resolveMavenPlaceholder(value) {
96+
const parts = value && value.match(/^\$\{(.*)\}$/);
97+
if (parts) {
98+
this._log.verbose(
99+
`"${value} contains a maven placeholder "${parts[1]}". Resolving from projects pom.xml...`);
100+
const pom = await this.getPom();
101+
let mvnValue;
102+
if (pom.project && pom.project.properties && pom.project.properties[parts[1]]) {
103+
mvnValue = pom.project.properties[parts[1]];
104+
} else {
105+
let obj = pom;
106+
parts[1].split(".").forEach((part) => {
107+
obj = obj && obj[part];
108+
});
109+
mvnValue = obj;
110+
}
111+
if (!mvnValue) {
112+
throw new Error(`"${value}" couldn't be resolved from maven property ` +
113+
`"${parts[1]}" of pom.xml of project ${this._project.metadata.name}`);
114+
}
115+
return mvnValue;
116+
} else {
117+
throw new Error(`"${value}" is not a maven placeholder`);
118+
}
119+
}
120+
121+
/**
122+
* Reads the projects pom.xml file
123+
*
124+
* @returns {Promise<object>} Resolves with a JSON representation of the content
125+
*/
126+
async _getPom() {
127+
if (this._pPom) {
128+
return this._pPom;
129+
}
130+
return this._pPom = this.getRootReader().byPath("/pom.xml")
131+
.then(async (resource) => {
132+
if (!resource) {
133+
throw new Error(
134+
`Could not find pom.xml in project ${this.getName()}`);
135+
}
136+
const content = await resource.getString();
137+
const xml2js = require("xml2js");
138+
const parser = new xml2js.Parser({
139+
explicitArray: false,
140+
ignoreAttrs: true
141+
});
142+
const readXML = promisify(parser.parseString);
143+
return readXML(content);
144+
}).catch((err) => {
145+
throw new Error(
146+
`Failed to read pom.xml for project ${this.getName()}: ${err.message}`);
147+
});
148+
}
149+
}
150+
151+
module.exports = ComponentProject;

lib/specifications/Extension.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
const AbstractSpecification = require("./AbstractSpecification");
1+
const Specification = require("./Specification");
22

3-
class Extension extends AbstractSpecification {
3+
class Extension extends Specification {
44
constructor(parameters) {
55
super(parameters);
66
if (new.target === Extension) {
7-
throw new TypeError("Class 'Project' is abstract");
7+
throw new TypeError("Class 'Project' is abstract. Please use one of the 'types' subclasses");
88
}
99
}
1010

lib/specifications/Project.js

Lines changed: 44 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,83 @@
1-
const AbstractSpecification = require("./AbstractSpecification");
1+
const Specification = require("./Specification");
22

3-
class Project extends AbstractSpecification {
3+
class Project extends Specification {
44
constructor(parameters) {
55
super(parameters);
66
if (new.target === Project) {
7-
throw new TypeError("Class 'Project' is abstract");
7+
throw new TypeError("Class 'Project' is abstract. Please use one of the 'types' subclasses");
88
}
9-
this._frameworkName = null;
10-
this._frameworkVersion = null;
11-
this._frameworkDependencies = null;
129
}
1310

1411
/* === Attributes === */
1512
/**
1613
* @public
1714
*/
1815
getFrameworkName() {
19-
return this._frameworkName;
16+
return this._config.framework && this._config.framework.name;
2017
}
2118
/**
2219
* @public
2320
*/
2421
getFrameworkVersion() {
25-
return this._frameworkVersion;
22+
return this._config.framework && this._config.framework.version;
2623
}
2724
/**
2825
* @public
2926
*/
3027
getFrameworkDependencies() {
3128
// TODO: Clone or freeze object before exposing?
32-
return this._frameworkDependencies || [];
29+
return this._config.framework && this._config.framework.libraries || [];
3330
}
3431

3532
isFrameworkProject() {
3633
return this.__id.startsWith("@openui5/") || this.__id.startsWith("@sapui5/");
3734
}
3835

36+
getCustomConfiguration() {
37+
return this._config.customConfiguration;
38+
}
39+
40+
getBuilderResourceExcludes() {
41+
return this._config.builder && this._config.builder.resources && this._config.builder.resources.excludes || [];
42+
}
43+
44+
getCustomTasks() {
45+
return this._config.builder && this._config.builder.customTasks || [];
46+
}
47+
48+
getServerSettings() {
49+
return this._config.server && this._config.server.settings;
50+
}
51+
52+
/* === Resource Access === */
53+
/**
54+
* @public
55+
*/
56+
getSourceReader() {
57+
throw new Error(`getSourceReader must be implemented by subclass ${this.constructor.name}`);
58+
}
59+
60+
/**
61+
* @public
62+
*/
63+
getRuntimeReader() {
64+
throw new Error(`getRuntimeReader must be implemented by subclass ${this.constructor.name}`);
65+
}
66+
67+
/**
68+
* @public
69+
*/
70+
getBuildtimeReader() {
71+
throw new Error(`getBuildtimeReader must be implemented by subclass ${this.constructor.name}`);
72+
}
73+
3974
/* === Internals === */
4075
/**
4176
* @private
4277
* @param {object} config Configuration object
4378
*/
4479
async _parseConfiguration(config) {
4580
await super._parseConfiguration(config);
46-
47-
if (config.framework) {
48-
if (config.framework.name) {
49-
this._frameworkName = config.framework.name;
50-
}
51-
if (config.framework.version) {
52-
this._frameworkVersion = config.framework.version;
53-
}
54-
if (config.framework.libraries) {
55-
this._frameworkDependencies = JSON.parse(JSON.stringify(config.framework.libraries));
56-
}
57-
}
5881
}
5982

6083
async _validate() {
@@ -65,74 +88,6 @@ class Project extends AbstractSpecification {
6588
`is of kind '${this.getKind()}'`);
6689
}
6790
}
68-
69-
/* === Helper === */
70-
/**
71-
* Checks whether a given string contains a maven placeholder.
72-
* E.g. <code>${appId}</code>.
73-
*
74-
* @param {string} value String to check
75-
* @returns {boolean} True if given string contains a maven placeholder
76-
*/
77-
_hasMavenPlaceholder(value) {
78-
return !!value.match(/^\$\{(.*)\}$/);
79-
}
80-
81-
/**
82-
* Resolves a maven placeholder in a given string using the projects pom.xml
83-
*
84-
* @param {string} value String containing a maven placeholder
85-
* @returns {Promise<string>} Resolved string
86-
*/
87-
async _resolveMavenPlaceholder(value) {
88-
const parts = value && value.match(/^\$\{(.*)\}$/);
89-
if (parts) {
90-
this._log.verbose(
91-
`"${value} contains a maven placeholder "${parts[1]}". Resolving from projects pom.xml...`);
92-
const pom = await this.getPom();
93-
let mvnValue;
94-
if (pom.project && pom.project.properties && pom.project.properties[parts[1]]) {
95-
mvnValue = pom.project.properties[parts[1]];
96-
} else {
97-
let obj = pom;
98-
parts[1].split(".").forEach((part) => {
99-
obj = obj && obj[part];
100-
});
101-
mvnValue = obj;
102-
}
103-
if (!mvnValue) {
104-
throw new Error(`"${value}" couldn't be resolved from maven property ` +
105-
`"${parts[1]}" of pom.xml of project ${this._project.metadata.name}`);
106-
}
107-
return mvnValue;
108-
} else {
109-
throw new Error(`"${value}" is not a maven placeholder`);
110-
}
111-
}
112-
113-
/**
114-
* Reads the projects pom.xml file
115-
*
116-
* @returns {Promise<object>} Resolves with a JSON representation of the content
117-
*/
118-
async _getPom() {
119-
if (this._pPom) {
120-
return this._pPom;
121-
}
122-
const fsPath = path.join(this._project.path, "pom.xml");
123-
return this._pPom = readFile(fsPath).then(async (content) => {
124-
const xml2js = require("xml2js");
125-
const parser = new xml2js.Parser({
126-
explicitArray: false,
127-
ignoreAttrs: true
128-
});
129-
const readXML = promisify(parser.parseString);
130-
return readXML(content);
131-
}).catch((err) => {
132-
throw new Error(
133-
`Failed to read pom.xml for project ${this._project.metadata.name}: ${err.message}`);
134-
});
135-
}
13691
}
13792

13893
module.exports = Project;

0 commit comments

Comments
 (0)