@ui5/cli 2.11.3 → 2.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,7 +2,42 @@
2
2
  All notable changes to this project will be documented in this file.
3
3
  This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
4
4
 
5
- A list of unreleased changes can be found [here](https://github.com/SAP/ui5-cli/compare/v2.11.3...HEAD).
5
+ A list of unreleased changes can be found [here](https://github.com/SAP/ui5-cli/compare/v2.14.0...HEAD).
6
+
7
+ <a name="v2.14.0"></a>
8
+ ## [v2.14.0] - 2021-10-19
9
+ ### Dependency Updates
10
+ - Bump [@ui5](https://github.com/ui5)/project from 2.5.0 to 2.6.0 [`2c42bba`](https://github.com/SAP/ui5-cli/commit/2c42bba826add655dd0bf44d4c78ff72258d10b2)
11
+ - Bump [@ui5](https://github.com/ui5)/server from 2.3.1 to 2.4.0 [`063b2f7`](https://github.com/SAP/ui5-cli/commit/063b2f77c936b90f1a2cd9febb7a5aed0f17fa20)
12
+ - Bump [@ui5](https://github.com/ui5)/builder from 2.11.0 to 2.11.1 [`11a0f5a`](https://github.com/SAP/ui5-cli/commit/11a0f5a391ca9e629b52b3046560678a8afeaf16)
13
+ - Bump [@ui5](https://github.com/ui5)/builder from 2.10.0 to 2.11.0 [`6f13917`](https://github.com/SAP/ui5-cli/commit/6f139171d3bd46da7bdb1c4c8015589e60fa14f6)
14
+
15
+
16
+ <a name="v2.13.0"></a>
17
+ ## [v2.13.0] - 2021-10-05
18
+ ### Bug Fixes
19
+ - Allow Node.js pre-release versions ([#458](https://github.com/SAP/ui5-cli/issues/458)) [`f6351c6`](https://github.com/SAP/ui5-cli/commit/f6351c663975f4ea14f08fa9a655bb6bf0447080)
20
+
21
+ ### Dependency Updates
22
+ - Bump [@ui5](https://github.com/ui5)/builder from 2.9.5 to 2.10.0 [`1d6a0f4`](https://github.com/SAP/ui5-cli/commit/1d6a0f423fc3fa782b341614d562c04292f00e1b)
23
+
24
+
25
+ <a name="v2.12.1"></a>
26
+ ## [v2.12.1] - 2021-08-25
27
+ ### Dependency Updates
28
+ - Bump [@ui5](https://github.com/ui5)/builder from 2.9.4 to 2.9.5 [`e25a630`](https://github.com/SAP/ui5-cli/commit/e25a630b03d0d68566b200e1346e25ed77f34c44)
29
+
30
+
31
+ <a name="v2.12.0"></a>
32
+ ## [v2.12.0] - 2021-07-23
33
+ ### Dependency Updates
34
+ - Bump [@ui5](https://github.com/ui5)/project from 2.4.0 to 2.5.0 [`0b4c2fb`](https://github.com/SAP/ui5-cli/commit/0b4c2fbc840024e30c1f85de441c5908a4774518)
35
+ - Bump [@ui5](https://github.com/ui5)/server from 2.3.0 to 2.3.1 [`ffbd9a5`](https://github.com/SAP/ui5-cli/commit/ffbd9a5bc0e9ac0d3dca4f66d0ab5a7758aaec3a)
36
+ - Bump [@ui5](https://github.com/ui5)/builder from 2.9.3 to 2.9.4 [`dfeb74e`](https://github.com/SAP/ui5-cli/commit/dfeb74ec96a5c14a500d56952f4727b1b7f0b4cd)
37
+
38
+ ### Features
39
+ - Support to only build certain dependencies ([#442](https://github.com/SAP/ui5-cli/issues/442)) [`5f941f1`](https://github.com/SAP/ui5-cli/commit/5f941f1e5d3041fc94f2e9e9eed14ad44add78aa)
40
+
6
41
 
7
42
  <a name="v2.11.3"></a>
8
43
  ## [v2.11.3] - 2021-07-01
@@ -661,6 +696,10 @@ Only Node.js v10 or higher is supported.
661
696
  <a name="v0.0.1"></a>
662
697
  ## v0.0.1 - 2018-06-06
663
698
 
699
+ [v2.14.0]: https://github.com/SAP/ui5-cli/compare/v2.13.0...v2.14.0
700
+ [v2.13.0]: https://github.com/SAP/ui5-cli/compare/v2.12.1...v2.13.0
701
+ [v2.12.1]: https://github.com/SAP/ui5-cli/compare/v2.12.0...v2.12.1
702
+ [v2.12.0]: https://github.com/SAP/ui5-cli/compare/v2.11.3...v2.12.0
664
703
  [v2.11.3]: https://github.com/SAP/ui5-cli/compare/v2.11.2...v2.11.3
665
704
  [v2.11.2]: https://github.com/SAP/ui5-cli/compare/v2.11.1...v2.11.2
666
705
  [v2.11.1]: https://github.com/SAP/ui5-cli/compare/v2.11.0...v2.11.1
package/bin/ui5.js CHANGED
@@ -14,7 +14,10 @@ try {
14
14
  }
15
15
  var nodeVersion = process.version;
16
16
  /* eslint-enable no-var */
17
- if (pkg.engines && pkg.engines.node && (!semver || !semver.satisfies(nodeVersion, pkg.engines.node))) {
17
+ if (
18
+ pkg.engines && pkg.engines.node &&
19
+ (!semver || !semver.satisfies(nodeVersion, pkg.engines.node, {includePrerelease: true}))
20
+ ) {
18
21
  console.log("==================== UNSUPPORTED NODE.JS VERSION ====================");
19
22
  console.log("You are using an unsupported version of Node.js");
20
23
  console.log("Detected version " + nodeVersion + " but " + pkg.name + " requires " + pkg.engines.node);
@@ -23,6 +26,17 @@ if (pkg.engines && pkg.engines.node && (!semver || !semver.satisfies(nodeVersion
23
26
  console.log("=====================================================================");
24
27
  process.exit(1);
25
28
  } else {
29
+ if (semver && semver.prerelease(nodeVersion)) {
30
+ console.log("====================== UNSTABLE NODE.JS VERSION =====================");
31
+ console.log("You are using an unstable version of Node.js");
32
+ console.log("Detected Node.js version " + nodeVersion);
33
+ console.log("");
34
+ console.log("=> Please note that an unstable version might cause unexpected");
35
+ console.log(" behavior. For productive use please consider using a stable");
36
+ console.log(" version of Node.js! For the release policy of Node.js, see");
37
+ console.log(" https://nodejs.org/en/about/releases");
38
+ console.log("=====================================================================");
39
+ }
26
40
  // Timeout is required to log info when importing from local installation
27
41
  setTimeout(() => {
28
42
  if (!process.env.UI5_CLI_NO_LOCAL) {
@@ -1,6 +1,7 @@
1
1
  // Build
2
2
 
3
3
  const baseMiddleware = require("../middlewares/base.js");
4
+ const buildHelper = require("../../utils/buildHelper");
4
5
 
5
6
  const build = {
6
7
  command: "build",
@@ -26,17 +27,51 @@ build.builder = function(cli) {
26
27
  builder: noop,
27
28
  middlewares: [baseMiddleware]
28
29
  })
29
- .command("self-contained", "Build project and create self-contained bundle", {
30
- handler: handleBuild,
31
- builder: noop,
32
- middlewares: [baseMiddleware]
33
- })
30
+ .command("self-contained",
31
+ "Build project and create self-contained bundle. " +
32
+ "Recommended to be used in conjunction with --all", {
33
+ handler: handleBuild,
34
+ builder: noop,
35
+ middlewares: [baseMiddleware]
36
+ })
34
37
  .option("all", {
35
38
  describe: "Include all project dependencies into build process",
36
39
  alias: "a",
37
40
  default: false,
38
41
  type: "boolean"
39
42
  })
43
+ .option("include-dependency", {
44
+ describe: "A list of dependencies to be included into the build process. You can use the asterisk '*' as" +
45
+ " an alias for including all dependencies into the build process. The listed dependencies cannot be" +
46
+ " overruled by dependencies defined in 'exclude-dependency'.",
47
+ type: "array"
48
+ })
49
+ .option("include-dependency-regexp", {
50
+ describe: "A list of regular expressions defining dependencies to be included into the build process." +
51
+ " This list is prioritized like 'include-dependency'.",
52
+ type: "array"
53
+ })
54
+ .option("include-dependency-tree", {
55
+ describe: "A list of dependencies to be included into the build process. Transitive dependencies are" +
56
+ " implicitly included and do not need to be part of this list. These dependencies overrule" +
57
+ " the selection of 'exclude-dependency-tree' but can be overruled by 'exclude-dependency'.",
58
+ type: "array"
59
+ })
60
+ .option("exclude-dependency", {
61
+ describe: "A list of dependencies to be excluded from the build process. The listed dependencies can" +
62
+ " be overruled by dependencies defined in 'include-dependency'.",
63
+ type: "array"
64
+ })
65
+ .option("exclude-dependency-regexp", {
66
+ describe: "A list of regular expressions defining dependencies to be excluded from the build process." +
67
+ " This list is prioritized like 'exclude-dependency'.",
68
+ type: "array"
69
+ })
70
+ .option("exclude-dependency-tree", {
71
+ describe: "A list of dependencies to be excluded from the build process. Transitive dependencies are" +
72
+ " implicitly included and do not need to be part of this list.",
73
+ type: "array"
74
+ })
40
75
  .option("dest", {
41
76
  describe: "Path of build destination",
42
77
  default: "./dist",
@@ -65,7 +100,8 @@ build.builder = function(cli) {
65
100
  describe: "Overrides the framework version defined by the project",
66
101
  type: "string"
67
102
  })
68
- .example("ui5 build --all", "Preload build for project and dependencies to \"./dist\"")
103
+ .example("ui5 build", "Preload build for project without dependencies")
104
+ .example("ui5 build self-contained --all", "Self-contained build for project including dependencies")
69
105
  .example("ui5 build --all --exclude-task=* --include-task=createDebugFiles generateAppPreload",
70
106
  "Build project and dependencies but only apply the createDebugFiles- and generateAppPreload tasks")
71
107
  .example("ui5 build --all --include-task=createDebugFiles --exclude-task=generateAppPreload",
@@ -98,11 +134,29 @@ async function handleBuild(argv) {
98
134
  }
99
135
 
100
136
  const tree = await normalizer.generateProjectTree(normalizerOptions);
137
+ const buildSettings = (tree.builder && tree.builder.settings) || {};
138
+
139
+ const {includedDependencies, excludedDependencies} = buildHelper.createDependencyLists({
140
+ tree: tree,
141
+ includeDependency: argv["include-dependency"],
142
+ includeDependencyRegExp: argv["include-dependency-regexp"],
143
+ includeDependencyTree: argv["include-dependency-tree"],
144
+ excludeDependency: argv["exclude-dependency"],
145
+ excludeDependencyRegExp: argv["exclude-dependency-regexp"],
146
+ excludeDependencyTree: argv["exclude-dependency-tree"],
147
+ defaultIncludeDependency: buildSettings.includeDependency,
148
+ defaultIncludeDependencyRegExp: buildSettings.includeDependencyRegExp,
149
+ defaultIncludeDependencyTree: buildSettings.includeDependencyTree
150
+ });
151
+ const buildAll = buildHelper.alignWithBuilderApi(argv.all, includedDependencies, excludedDependencies);
152
+
101
153
  await builder.build({
102
154
  tree: tree,
103
155
  destPath: argv.dest,
104
156
  cleanDest: argv["clean-dest"],
105
- buildDependencies: argv.all,
157
+ buildDependencies: buildAll,
158
+ includedDependencies: includedDependencies,
159
+ excludedDependencies: excludedDependencies,
106
160
  dev: command === "dev",
107
161
  selfContained: command === "self-contained",
108
162
  jsdoc: command === "jsdoc",
package/lib/init/init.js CHANGED
@@ -66,7 +66,7 @@ function getProjectType(hasWebapp, hasSrc, hasTest) {
66
66
  */
67
67
  async function init({cwd = "./"} = {}) {
68
68
  const projectConfig = {
69
- specVersion: "2.4",
69
+ specVersion: "2.6",
70
70
  metadata: {}
71
71
  };
72
72
  let pkg;
@@ -0,0 +1,216 @@
1
+ const log = require("@ui5/logger").getLogger("cli:utils:buildHelper");
2
+
3
+ /**
4
+ * Creates an object containing the flattened project dependency tree. Each dependency is defined as an object key while
5
+ * its value is an array of all of its transitive dependencies.
6
+ *
7
+ * @param {object} tree Project tree as generated by the [@ui5/project.normalizer]{@link module:@ui5/project.normalizer}
8
+ * @returns {object<string, string[]>} An object with dependency names as key and each with an array of its transitive
9
+ * dependencies as value
10
+ */
11
+ function getFlattenedDependencyTree(tree) {
12
+ const dependencyInfo = {};
13
+
14
+ function _getTransitiveDependencies(project, dependencies) {
15
+ project.dependencies.forEach((dep) => {
16
+ if (!dependencies.includes(dep.metadata.name)) {
17
+ dependencies.push(dep.metadata.name);
18
+ _getTransitiveDependencies(dep, dependencies);
19
+ }
20
+ });
21
+ return dependencies;
22
+ }
23
+ function _processDependencies(project) {
24
+ project.dependencies.forEach((dep) => {
25
+ if (!dependencyInfo[dep.metadata.name]) {
26
+ dependencyInfo[dep.metadata.name] = _getTransitiveDependencies(dep, []);
27
+ _processDependencies(dep);
28
+ }
29
+ });
30
+ }
31
+
32
+ _processDependencies(tree);
33
+ return dependencyInfo;
34
+ }
35
+
36
+ /**
37
+ * Creates dependency lists for 'includedDependencies' and 'excludedDependencies'. Regular expressions are directly
38
+ * applied to a list of all project dependencies so that they don't need to be evaluated in later processing steps.
39
+ * Generally, includes are handled with a higher priority than excludes. Additionally, operations for processing
40
+ * transitive dependencies are handled with a lower priority than explicitly mentioned dependencies. The default
41
+ * dependencies set in the build settings are appended in the end.
42
+ *
43
+ * The priority of the various dependency lists is applied in the following order, but note that a later list can't
44
+ * overrule earlier ones:
45
+ * <ol>
46
+ * <li>includeDependency, includeDependencyRegExp</li>
47
+ * <li>excludeDependency, excludeDependencyRegExp</li>
48
+ * <li>includeDependencyTree</li>
49
+ * <li>excludeDependencyTree</li>
50
+ * <li>defaultIncludeDependency, defaultIncludeDependencyRegExp, defaultIncludeDependencyTree</li>
51
+ * </ol>
52
+ *
53
+ * @param {object} parameters Parameters
54
+ * @param {object} parameters.tree Project tree as generated by the
55
+ * [@ui5/project.normalizer]{@link module:@ui5/project.normalizer}
56
+ * @param {string[]} parameters.includeDependency The dependencies to be considered in 'includedDependencies'; the
57
+ * "*" character can be used as wildcard for all dependencies and is an alias for the CLI option "--all"
58
+ * @param {string[]} parameters.includeDependencyRegExp Strings which are interpreted as regular expressions
59
+ * to describe the selection of dependencies to be considered in 'includedDependencies'
60
+ * @param {string[]} parameters.includeDependencyTree The dependencies to be considered in 'includedDependencies';
61
+ * transitive dependencies are also appended
62
+ * @param {string[]} parameters.excludeDependency The dependencies to be considered in 'excludedDependencies'
63
+ * @param {string[]} parameters.excludeDependencyRegExp Strings which are interpreted as regular expressions
64
+ * to describe the selection of dependencies to be considered in 'excludedDependencies'
65
+ * @param {string[]} parameters.excludeDependencyTree The dependencies to be considered in 'excludedDependencies';
66
+ * transitive dependencies are also appended
67
+ * @param {string[]} parameters.defaultIncludeDependency Same as 'includeDependency' parameter; used for build
68
+ * settings
69
+ * @param {string[]} parameters.defaultIncludeDependencyRegExp Same as 'includeDependencyRegExp' parameter; used
70
+ * for build settings
71
+ * @param {string[]} parameters.defaultIncludeDependencyTree Same as 'includeDependencyTree' parameter; used for
72
+ * build settings
73
+ * @returns {{includedDependencies:string[],excludedDependencies:string[]}} An object containing the
74
+ * 'includedDependencies' and 'excludedDependencies'
75
+ */
76
+ function createDependencyLists({
77
+ tree,
78
+ includeDependency = [], includeDependencyRegExp = [], includeDependencyTree = [],
79
+ excludeDependency = [], excludeDependencyRegExp = [], excludeDependencyTree = [],
80
+ defaultIncludeDependency = [], defaultIncludeDependencyRegExp = [], defaultIncludeDependencyTree = []
81
+ }) {
82
+ if (
83
+ !includeDependency.length && !includeDependencyRegExp.length && !includeDependencyTree.length &&
84
+ !excludeDependency.length && !excludeDependencyRegExp.length && !excludeDependencyTree.length &&
85
+ !defaultIncludeDependency.length && !defaultIncludeDependencyRegExp.length &&
86
+ !defaultIncludeDependencyTree.length
87
+ ) {
88
+ return {includedDependencies: [], excludedDependencies: []};
89
+ }
90
+
91
+ const flattenedDependencyTree = getFlattenedDependencyTree(tree);
92
+
93
+ function isExcluded(excludeList, depName) {
94
+ return excludeList && excludeList.has(depName);
95
+ }
96
+ function processDependencies({targetList, dependencies, dependenciesRegExp = [], excludeList, handleSubtree}) {
97
+ if (handleSubtree && dependenciesRegExp.length) {
98
+ throw new Error("dependenciesRegExp can't be combined with handleSubtree:true option");
99
+ }
100
+ dependencies.forEach((depName) => {
101
+ if (depName === "*") {
102
+ targetList.add(depName);
103
+ } else if (flattenedDependencyTree[depName]) {
104
+ if (!isExcluded(excludeList, depName)) {
105
+ targetList.add(depName);
106
+ }
107
+ if (handleSubtree) {
108
+ flattenedDependencyTree[depName].forEach((dep) => {
109
+ if (!isExcluded(excludeList, dep)) {
110
+ targetList.add(dep);
111
+ }
112
+ });
113
+ }
114
+ } else {
115
+ log.warn(
116
+ `Could not find dependency "${depName}" for project ${tree.metadata.name}. Dependency filter is ` +
117
+ `ignored`);
118
+ }
119
+ });
120
+ dependenciesRegExp.map((exp) => new RegExp(exp)).forEach((regExp) => {
121
+ for (const depName in flattenedDependencyTree) {
122
+ if (regExp.test(depName) && !isExcluded(excludeList, depName)) {
123
+ targetList.add(depName);
124
+ }
125
+ }
126
+ });
127
+ }
128
+
129
+ const includedDependencies = new Set();
130
+ const excludedDependencies = new Set();
131
+
132
+ // add dependencies defined in includeDependency and includeDependencyRegExp to the list of includedDependencies
133
+ processDependencies({
134
+ targetList: includedDependencies,
135
+ dependencies: includeDependency,
136
+ dependenciesRegExp: includeDependencyRegExp
137
+ });
138
+ // add dependencies defined in excludeDependency and excludeDependencyRegExp to the list of excludedDependencies
139
+ processDependencies({
140
+ targetList: excludedDependencies,
141
+ dependencies: excludeDependency,
142
+ dependenciesRegExp: excludeDependencyRegExp
143
+ });
144
+ // add dependencies defined in includeDependencyTree with their transitive dependencies to the list of
145
+ // includedDependencies; due to prioritization only those dependencies are added which are not excluded
146
+ // by excludedDependencies
147
+ processDependencies({
148
+ targetList: includedDependencies,
149
+ dependencies: includeDependencyTree,
150
+ excludeList: excludedDependencies,
151
+ handleSubtree: true
152
+ });
153
+ // add dependencies defined in excludeDependencyTree with their transitive dependencies to the list of
154
+ // excludedDependencies; due to prioritization only those dependencies are added which are not excluded
155
+ // by includedDependencies
156
+ processDependencies({
157
+ targetList: excludedDependencies,
158
+ dependencies: excludeDependencyTree,
159
+ excludeList: includedDependencies,
160
+ handleSubtree: true
161
+ });
162
+ // due to the lowest priority only add the dependencies defined in build settings if they are not excluded
163
+ // by any other dependency defined in excludedDependencies
164
+ processDependencies({
165
+ targetList: includedDependencies,
166
+ dependencies: defaultIncludeDependency,
167
+ dependenciesRegExp: defaultIncludeDependencyRegExp,
168
+ excludeList: excludedDependencies
169
+ });
170
+ processDependencies({
171
+ targetList: includedDependencies,
172
+ dependencies: defaultIncludeDependencyTree,
173
+ excludeList: excludedDependencies,
174
+ handleSubtree: true
175
+ });
176
+
177
+ return {
178
+ includedDependencies: Array.from(includedDependencies),
179
+ excludedDependencies: Array.from(excludedDependencies)
180
+ };
181
+ }
182
+
183
+ /**
184
+ * Returns whether project dependencies have to be built influenced by <code>includedDependencies</code> and
185
+ * <code>excludedDependencies</code>.
186
+ * If only selected dependencies (via <code>includedDependencies</code>) have to be built, the "*" character
187
+ * is added to the <code>excludedDependencies</code> to make sure that all other dependencies are
188
+ * excluded.
189
+ * In case a "*" character is included in <code>includedDependencies</code>, it is removed and the
190
+ * <code>buildAll</code> flag is set to <code>true</code> as it behaves as an alias.
191
+ *
192
+ * @param {boolean} buildAll The value of the <code>all</code> command line parameter to decide if project
193
+ * dependencies have to be built
194
+ * @param {string[]} includedDependencies The list of included dependencies
195
+ * @param {string[]} excludedDependencies The list of excluded dependencies
196
+ * @returns {boolean} Whether it is required to build project dependencies
197
+ */
198
+ function alignWithBuilderApi(buildAll, includedDependencies, excludedDependencies) {
199
+ if ((!buildAll && !includedDependencies.includes("*")) && includedDependencies.length) {
200
+ excludedDependencies.push("*");
201
+ }
202
+ if (includedDependencies.includes("*")) {
203
+ buildAll = true;
204
+ includedDependencies.splice(includedDependencies.indexOf("*"), 1);
205
+ }
206
+ if (!buildAll && includedDependencies.length) {
207
+ buildAll = true;
208
+ }
209
+ return buildAll;
210
+ }
211
+
212
+ module.exports = {
213
+ getFlattenedDependencyTree,
214
+ createDependencyLists,
215
+ alignWithBuilderApi
216
+ };