generator-easy-ui5 3.4.0 → 3.5.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
@@ -1,8 +1,9 @@
1
- # [3.3.0](https://github.com/SAP/generator-easy-ui5/compare/v3.2.0...v3.3.0) (2022-02-21)
1
+ # [3.4.0](https://github.com/SAP/generator-easy-ui5/compare/v3.2.0...v3.4.0) (2022-06-25)
2
2
 
3
3
 
4
4
  ### Bug Fixes
5
5
 
6
+ * **postinstall:** allow usage of NPM config for ghAuthToken to avoid rate limit ([#104](https://github.com/SAP/generator-easy-ui5/issues/104)) ([371d7fb](https://github.com/SAP/generator-easy-ui5/commit/371d7fbc82b8a59cef896197b99239b505b3cd90)), closes [#100](https://github.com/SAP/generator-easy-ui5/issues/100)
6
7
  * **postinstall:** avoid non-existing node_modules ([#98](https://github.com/SAP/generator-easy-ui5/issues/98)) ([f93c7c9](https://github.com/SAP/generator-easy-ui5/commit/f93c7c99b9e5df7af801a085afe72be85e462007))
7
8
  * usage of proper gh org for logging and download ([#94](https://github.com/SAP/generator-easy-ui5/issues/94)) ([a88d4db](https://github.com/SAP/generator-easy-ui5/commit/a88d4dbb0a1f5ed3cf60f7ed0297c651222a83fb))
8
9
  * use the org name of the selected generator for downloading the corresponding repo ([d9ca4dc](https://github.com/SAP/generator-easy-ui5/commit/d9ca4dc3170e0507199799d2e14db327cba4d871))
@@ -10,6 +11,7 @@
10
11
 
11
12
  ### Features
12
13
 
14
+ * allow ghAuthToken as NPM configuration ([#103](https://github.com/SAP/generator-easy-ui5/issues/103)) ([5e3d928](https://github.com/SAP/generator-easy-ui5/commit/5e3d92807e881d0ade80251bc8cc1bdde85142be))
13
15
  * allow to run easy-ui5 embedded ([#99](https://github.com/SAP/generator-easy-ui5/issues/99)) ([f4952c4](https://github.com/SAP/generator-easy-ui5/commit/f4952c442c9563a51c48b8edc25843f097fce4c4))
14
16
 
15
17
 
@@ -8,7 +8,9 @@ const { hasYarn } = require("yarn-or-npm");
8
8
  const path = require("path");
9
9
  const fs = require("fs");
10
10
  const { rm } = require("fs").promises;
11
+ const glob = require("glob");
11
12
 
13
+ const { request } = require("@octokit/request");
12
14
  const { Octokit } = require("@octokit/rest");
13
15
  const { throttling } = require("@octokit/plugin-throttling");
14
16
  const MyOctokit = Octokit.plugin(throttling);
@@ -62,19 +64,32 @@ const generatorOptions = {
62
64
  type: Boolean,
63
65
  description: "List the available subcommands of the generator",
64
66
  },
65
- verbose: {
67
+ skipUpdate: {
66
68
  type: Boolean,
67
- description: "Enable detailed logging",
69
+ description: "Skip the update of the plugin generator",
68
70
  },
69
- skipUpdate: {
71
+ forceUpdate: {
70
72
  type: Boolean,
71
- description: "Skip the update of the plugin generators",
73
+ description: "Force the update of the plugin generator",
74
+ },
75
+ offline: {
76
+ type: Boolean,
77
+ alias: "o",
78
+ description: "Running easy-ui5 in offline mode",
79
+ },
80
+ verbose: {
81
+ type: Boolean,
82
+ description: "Enable detailed logging",
72
83
  },
73
84
  plugins: {
74
85
  type: Boolean,
75
86
  alias: "p",
76
87
  description: "Get detailed version information",
77
- }
88
+ },
89
+ next: {
90
+ type: Boolean,
91
+ description: "Preview the next mode to consume templates from bestofui5.org",
92
+ },
78
93
  };
79
94
 
80
95
  const generatorArgs = {
@@ -162,7 +177,6 @@ module.exports = class extends Generator {
162
177
 
163
178
  // log the plugins and configuration
164
179
  if (this.options.plugins) {
165
- const glob = require("glob");
166
180
  const yeoman = require("yeoman-environment/package.json");
167
181
 
168
182
  const components = {
@@ -179,7 +193,7 @@ module.exports = class extends Generator {
179
193
 
180
194
  this.log(chalk.green("\nAvailable generators:"));
181
195
  glob.sync(`${pluginsHome}/*/package.json`).forEach((plugin) => {
182
- const name = plugin.match(/.*\/(.+)\/package\.json/)[1];
196
+ const name = plugin.match(/.*\/generator-(.+)\/package\.json/)[1];
183
197
  const lib = require(plugin);
184
198
  this.log(` - ${chalk.green(name)}: ${lib.version}`);
185
199
  });
@@ -188,30 +202,38 @@ module.exports = class extends Generator {
188
202
  }
189
203
 
190
204
  // create the octokit client to retrieve the generators from GH org
191
- const octokit = new MyOctokit({
192
- userAgent: `${this.rootGeneratorName()}:${this.rootGeneratorVersion()}`,
193
- auth: this.options.ghAuthToken,
194
- throttle: {
195
- onRateLimit: (retryAfter, options) => {
196
- this.log(
197
- `${chalk.yellow("Hit the GitHub API limit!")} Request quota exhausted for this request.`
198
- );
199
-
200
- if (options.request.retryCount === 0) {
201
- // only retries once
202
- this.log(`Retrying after ${retryAfter} seconds. Alternatively, you can cancel this operation and supply an auth token with the \`--ghAuthToken\` option. For more details, run \`yo easy-ui5 --help\`. `);
203
- return true;
204
- }
205
- },
206
- onAbuseLimit: () => {
207
- // does not retry, only logs a warning
208
- this.log(
209
- `${chalk.red("Hit the GitHub API limit again!")} Please supply an auth token with the \`--ghAuthToken\` option. For more details, run \`yo easy-ui5 --help\` `
210
- );
211
-
212
- },
213
- }
214
- });
205
+ // when not running in offline mode!
206
+ let octokit;
207
+ if (this.options.offline) {
208
+ this.log(
209
+ `Running in ${chalk.yellow(
210
+ "offline"
211
+ )} mode!`
212
+ );
213
+ } else {
214
+ octokit = new MyOctokit({
215
+ userAgent: `${this.rootGeneratorName()}:${this.rootGeneratorVersion()}`,
216
+ auth: this.options.ghAuthToken,
217
+ throttle: {
218
+ onRateLimit: (retryAfter, options) => {
219
+ this.log(
220
+ `${chalk.yellow("Hit the GitHub API limit!")} Request quota exhausted for this request.`
221
+ );
222
+ if (options.request.retryCount === 0) {
223
+ // only retries once
224
+ this.log(`Retrying after ${retryAfter} seconds. Alternatively, you can cancel this operation and supply an auth token with the \`--ghAuthToken\` option. For more details, run \`yo easy-ui5 --help\`. `);
225
+ return true;
226
+ }
227
+ },
228
+ onAbuseLimit: () => {
229
+ // does not retry, only logs a warning
230
+ this.log(
231
+ `${chalk.red("Hit the GitHub API limit again!")} Please supply an auth token with the \`--ghAuthToken\` option. For more details, run \`yo easy-ui5 --help\` `
232
+ );
233
+ },
234
+ }
235
+ });
236
+ }
215
237
 
216
238
  // helper for filtering repos with corresponding subGenerator prefix
217
239
  const filterReposWithSubGeneratorPrefix = (repos, subGeneratorPrefix) => {
@@ -228,7 +250,7 @@ module.exports = class extends Generator {
228
250
  subGeneratorName: repo.name.substring(subGeneratorPrefix.length),
229
251
  };
230
252
  });
231
- }
253
+ };
232
254
 
233
255
  // helper to retrieve the available repositories for a GH org
234
256
  const listGeneratorsForOrg = async (ghOrg, subGeneratorPrefix) => {
@@ -236,7 +258,7 @@ module.exports = class extends Generator {
236
258
  org: ghOrg,
237
259
  });
238
260
  return filterReposWithSubGeneratorPrefix(response?.data, subGeneratorPrefix);
239
- }
261
+ };
240
262
 
241
263
  // helper to retrieve the available repositories for a GH user
242
264
  const listGeneratorsForUser = async (ghUser, subGeneratorPrefix) => {
@@ -244,62 +266,133 @@ module.exports = class extends Generator {
244
266
  username: ghUser,
245
267
  });
246
268
  return filterReposWithSubGeneratorPrefix(response?.data, subGeneratorPrefix);
247
- }
269
+ };
248
270
 
249
- // retrieve the available repositories
250
- let availGenerators;
251
- try {
252
- availGenerators = await listGeneratorsForOrg(this.options.ghOrg, this.options.subGeneratorPrefix);
253
- } catch (e) {
254
- console.error(`Failed to connect to GitHub to retrieve available generators for "${this.options.ghOrg}" organization! Run with --verbose for details!`);
255
- if (this.options.verbose) {
256
- console.error(e);
257
- }
258
- return;
259
- }
260
- try {
261
- if (this.options.addGhOrg && this.options.addSubGeneratorPrefix) {
262
- availGenerators = availGenerators.concat(await listGeneratorsForOrg(this.options.addGhOrg, this.options.addSubGeneratorPrefix));
263
- }
264
- } catch (e) {
265
- if (this.options.verbose) {
266
- this.log(`Failed to connect to GitHub retrieve additional generators for "${this.options.addGhOrg}" organization! Try to retrieve for user...`);
267
- }
268
- try {
269
- availGenerators = availGenerators.concat(await listGeneratorsForUser(this.options.addGhOrg, this.options.addSubGeneratorPrefix));
270
- } catch (e) {
271
- console.error(`Failed to connect to GitHub to retrieve additional generators for organization or user "${this.options.addGhOrg}"! Run with --verbose for details!`);
271
+ // determine the generator to be used
272
+ let generator;
273
+
274
+ // try to identify whether concrete generator is defined
275
+ if (!generator) {
276
+ // determine generator by ${owner}/${repo}(!${dir})? syntax, e.g.:
277
+ // > yo easy-ui5 SAP-samples/ui5-typescript-tutorial
278
+ // > yo easy-ui5 SAP-samples/ui5-typescript-tutorial#1.0
279
+ // > yo easy-ui5 SAP-samples/ui5-typescript-tutorial\!/generator
280
+ // > yo easy-ui5 SAP-samples/ui5-typescript-tutorial\!/generator#1.0
281
+ const reGenerator = /([^\/]+)\/([^\!\#]+)(?:\!([^\#]+))?(?:\#(.+))?/;
282
+ const matchGenerator = reGenerator.exec(this.options.generator);
283
+ if (matchGenerator) {
284
+ // derive and path the generator information from command line
285
+ const [owner, repo, dir = "/generator", branch] = matchGenerator.slice(1);
286
+ generator = {
287
+ org: owner,
288
+ name: repo,
289
+ branch,
290
+ dir,
291
+ pluginPath: `_/${owner}/${repo}`,
292
+ };
293
+ // log which generator is being used!
272
294
  if (this.options.verbose) {
273
- console.error(e);
295
+ this.log(
296
+ `Using generator ${chalk.green(
297
+ `${owner}/${repo}!${dir}${branch ? "#" + branch : ""}`
298
+ )}`
299
+ );
274
300
  }
275
- return;
276
301
  }
277
302
  }
278
303
 
279
- // download the generator from GH (or the test generator)
280
- let generatorPath;
281
- if (this.options.generator === "test") {
282
- generatorPath = path.join(
283
- __dirname,
284
- "../../plugin-generators/generator-ui5-test"
285
- );
286
- } else {
304
+ // retrieve the available repositories (if no generator is specified specified directly)
305
+ let availGenerators;
306
+ if (!generator) {
307
+ if (this.options.offline) {
308
+ availGenerators = glob.sync(`${pluginsHome}/generator-*/package.json`).map((plugin) => {
309
+ const match = plugin.match(/.*\/(generator-(.+))\/package\.json/);
310
+ return {
311
+ org: "local",
312
+ name: match[1],
313
+ subGeneratorName: match[2].match(/(?:ui5-)?(.*)/)?.[1] || match[2],
314
+ local: true,
315
+ }
316
+ });
317
+ } else {
318
+ if (this.options.next) {
319
+ // check bestofui5.org for generators
320
+ try {
321
+ const response = await request({
322
+ method: "GET",
323
+ url: "https://raw.githubusercontent.com/ui5-community/bestofui5-data/live-data/data/data.json",
324
+ });
325
+ const data = JSON.parse(response.data);
326
+
327
+ availGenerators = data?.packages?.filter(entry => {
328
+ return entry.type === "generator";
329
+ }).map(entry => {
330
+ return {
331
+ org: entry.gitHubOwner,
332
+ name: entry.gitHubRepo,
333
+ subGeneratorName: entry.gitHubRepo.match(/(?:generator-(?:ui5-)?)(.*)/)?.[1] || entry.gitHubRepo,
334
+ };
335
+ });
336
+ } catch (e) {
337
+ console.error(`Failed to connect to bestofui5.org to retrieve all available generators! Run with --verbose for details!`);
338
+ if (this.options.verbose) {
339
+ console.error(e);
340
+ }
341
+ return;
342
+ }
343
+ } else {
344
+ // check the main GH org for generators
345
+ try {
346
+ availGenerators = await listGeneratorsForOrg(this.options.ghOrg, this.options.subGeneratorPrefix);
347
+ } catch (e) {
348
+ console.error(`Failed to connect to GitHub to retrieve all available generators for "${this.options.ghOrg}" organization! Run with --verbose for details!`);
349
+ if (this.options.verbose) {
350
+ console.error(e);
351
+ }
352
+ return;
353
+ }
354
+
355
+ // check the additional GH org for generators with a different prefix
356
+ try {
357
+ if (this.options.addGhOrg && this.options.addSubGeneratorPrefix) {
358
+ availGenerators = availGenerators.concat(await listGeneratorsForOrg(this.options.addGhOrg, this.options.addSubGeneratorPrefix));
359
+ }
360
+ } catch (e) {
361
+ if (this.options.verbose) {
362
+ this.log(`Failed to connect to GitHub retrieve additional generators for "${this.options.addGhOrg}" organization! Try to retrieve for user...`);
363
+ }
364
+ try {
365
+ availGenerators = availGenerators.concat(await listGeneratorsForUser(this.options.addGhOrg, this.options.addSubGeneratorPrefix));
366
+ } catch (e) {
367
+ console.error(`Failed to connect to GitHub to retrieve additional generators for organization or user "${this.options.addGhOrg}"! Run with --verbose for details!`);
368
+ if (this.options.verbose) {
369
+ console.error(e);
370
+ }
371
+ return;
372
+ }
373
+ }
374
+ }
375
+ }
376
+ }
287
377
 
378
+ // if no generator is provided and doesn't exist, ask for generator name
379
+ if (!generator) {
288
380
  // check for provided generator being available on GH
289
- let generator = this.options.generator && availGenerators.find((repo) =>
381
+ generator = this.options.generator && availGenerators.find((repo) =>
290
382
  repo.subGeneratorName === this.options.generator
291
383
  );
292
384
 
293
385
  // if no generator is provided and doesn't exist, ask for generator name
294
- if (!generator) {
295
- if (this.options.generator) {
296
- this.log(
297
- `The generator ${chalk.red(
298
- this.options.generator
299
- )} was not found. Please select an existing generator!`
300
- );
301
- }
386
+ if (this.options.generator && !generator) {
387
+ this.log(
388
+ `The generator ${chalk.red(
389
+ this.options.generator
390
+ )} was not found. Please select an existing generator!`
391
+ );
392
+ }
302
393
 
394
+ // still not found, select a generator
395
+ if (!generator) {
303
396
  const generatorIdx = (
304
397
  await this.prompt([
305
398
  {
@@ -315,36 +408,54 @@ module.exports = class extends Generator {
315
408
  ).generator;
316
409
  generator = availGenerators[generatorIdx];
317
410
  }
411
+ }
318
412
 
319
- // fetch the available branches to retrieve the latest commit SHA
320
- let reqBranch;
413
+ let generatorPath = path.join(pluginsHome, generator.pluginPath || generator.name);
414
+ if (!this.options.offline) {
415
+ // lookup the default path of the generator if not set
416
+ if (!generator.branch) {
417
+ try {
418
+ const repoInfo = await octokit.repos.get({
419
+ owner: generator.org,
420
+ repo: generator.name,
421
+ });
422
+ generator.branch = repoInfo.data.default_branch;
423
+ } catch (e) {
424
+ console.error(`Generator "${owner}/${repo}!${dir}${branch ? "#" + branch : ""}" not found! Run with --verbose for details!`);
425
+ if (this.options.verbose) {
426
+ console.error(e);
427
+ }
428
+ return;
429
+ }
430
+ }
431
+ // fetch the branch to retrieve the latest commit SHA
432
+ let commitSHA;
321
433
  try {
322
- reqBranch = await octokit.repos.getBranch({
434
+ // determine the commitSHA
435
+ const reqBranch = await octokit.repos.getBranch({
323
436
  owner: generator.org,
324
437
  repo: generator.name,
325
438
  branch: generator.branch,
326
439
  });
440
+ commitSHA = reqBranch.data.commit.sha;
327
441
  } catch (e) {
328
- console.error(chalk.red(`Failed to retrieve the default branch for repository "${generator.name}" for "${generator.org}" organization! Run with --verbose for details!`));
442
+ console.error(chalk.red(`Failed to retrieve the branch "${generator.branch}" for repository "${generator.name}" for "${generator.org}" organization! Run with --verbose for details!`));
329
443
  if (this.options.verbose) {
330
444
  console.error(chalk.red(e.message));
331
445
  }
332
446
  return;
333
447
  }
334
-
335
- const commitSHA = reqBranch.data.commit.sha;
336
-
448
+
337
449
  if (this.options.verbose) {
338
450
  this.log(
339
- `Using commit ${commitSHA} from @${generator.org}/${generator.name}#${generator.default_branch}...`
451
+ `Using commit ${commitSHA} from @${generator.org}/${generator.name}#${generator.branch}...`
340
452
  );
341
453
  }
342
- generatorPath = path.join(pluginsHome, generator.name);
343
454
  const shaMarker = path.join(generatorPath, `.${commitSHA}`);
344
-
455
+
345
456
  if (fs.existsSync(generatorPath) && !this.options.skipUpdate) {
346
457
  // check if the SHA marker exists to know whether the generator is up-to-date or not
347
- if (!fs.existsSync(shaMarker)) {
458
+ if (this.options.forceUpdate || !fs.existsSync(shaMarker)) {
348
459
  if (this.options.verbose) {
349
460
  this.log(`Generator "${generator.name}" in "${generatorPath}" is outdated...`);
350
461
  }
@@ -353,7 +464,7 @@ module.exports = class extends Generator {
353
464
  await rm(generatorPath, { recursive: true });
354
465
  }
355
466
  }
356
-
467
+
357
468
  // re-fetch the generator and extract into local plugin folder
358
469
  if (!fs.existsSync(generatorPath)) {
359
470
  if (this.options.verbose) {
@@ -370,9 +481,14 @@ module.exports = class extends Generator {
370
481
  const zipEntries = zip.getEntries();
371
482
  zipEntries.forEach((entry) => {
372
483
  const match =
373
- !entry.isDirectory && entry.entryName.match(/[^\/]+\/(.+)/);
374
- if (match) {
375
- const entryPath = match[1].slice(0, entry.name.length * -1);
484
+ !entry.isDirectory && entry.entryName.match(/[^\/]+(\/.+)/);
485
+ let entryPath;
486
+ if (generator.dir && match && match[1].startsWith(generator.dir)) {
487
+ entryPath = path.dirname(match[1].substring(generator.dir.length));
488
+ } else if (!generator.dir && match) {
489
+ entryPath = path.dirname(match[1]);
490
+ }
491
+ if (entryPath) {
376
492
  zip.extractEntryTo(
377
493
  entry,
378
494
  path.join(generatorPath, entryPath),
@@ -380,9 +496,9 @@ module.exports = class extends Generator {
380
496
  true
381
497
  );
382
498
  }
383
- });
499
+ });
384
500
  fs.writeFileSync(shaMarker, commitSHA);
385
-
501
+
386
502
  // run yarn/npm install
387
503
  if (this.options.verbose) {
388
504
  this.log("Installing the plugin dependencies...");
@@ -403,9 +519,10 @@ module.exports = class extends Generator {
403
519
  });
404
520
  }.bind(this));
405
521
  }
406
- }
522
+
523
+ this._clearBusy(true);
407
524
 
408
- this._clearBusy(true);
525
+ }
409
526
 
410
527
  // filter the local options and the help command
411
528
  const opts = Object.keys(this._options).filter(
@@ -523,7 +640,7 @@ module.exports = class extends Generator {
523
640
  }
524
641
 
525
642
  if (this.options.verbose) {
526
- this.log(`Calling ${chalk.red(subGenerator)}...`);
643
+ this.log(`Calling ${chalk.red(subGenerator)}...\n \\_ in: ${generatorPath}`);
527
644
  }
528
645
 
529
646
  // finally, run the subgenerator
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "generator-easy-ui5",
3
- "version": "3.4.0",
3
+ "version": "3.5.0",
4
4
  "description": "Generator for UI5-based project",
5
5
  "main": "generators/app/index.js",
6
6
  "files": [
@@ -19,6 +19,7 @@
19
19
  "startSubGen": "yo easy-ui5 project app",
20
20
  "workaround": "find . -name '.DS_Store' -delete",
21
21
  "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0",
22
+ "postversion": "npm run changelog && git commit --all --amend --no-edit",
22
23
  "prepare": "husky install",
23
24
  "hooks:commit-msg": "commitlint -e"
24
25
  },
@@ -42,14 +43,14 @@
42
43
  },
43
44
  "homepage": "https://github.com/SAP/generator-easy-ui5#readme",
44
45
  "dependencies": {
45
- "@octokit/plugin-throttling": "^3.5.2",
46
- "@octokit/rest": "^18.12.0",
46
+ "@octokit/plugin-throttling": "^4.1.0",
47
+ "@octokit/rest": "^19.0.3",
47
48
  "adm-zip": "^0.5.9",
48
49
  "chalk": "^4.1.2",
49
50
  "colors": "1.4.0",
50
51
  "glob": "^7.2.0",
51
52
  "libnpmconfig": "^1.2.1",
52
- "mocha": "^9.2.0",
53
+ "mocha": "^10.0.0",
53
54
  "rimraf": "^3.0.2",
54
55
  "yarn-or-npm": "^3.0.1",
55
56
  "yeoman-assert": "^3.1.1",
@@ -59,12 +60,12 @@
59
60
  "yosay": "^2.0.2"
60
61
  },
61
62
  "devDependencies": {
62
- "@commitlint/cli": "16.1.0",
63
- "@commitlint/config-conventional": "16.0.0",
63
+ "@commitlint/cli": "17.0.3",
64
+ "@commitlint/config-conventional": "17.0.3",
64
65
  "conventional-changelog-cli": "^2.2.2",
65
66
  "cz-conventional-changelog": "3.3.0",
66
- "husky": "^7.0.4",
67
- "prettier": "2.5.1"
67
+ "husky": "^8.0.1",
68
+ "prettier": "2.7.1"
68
69
  },
69
70
  "config": {
70
71
  "commitizen": {
@@ -75,5 +76,8 @@
75
76
  "extends": [
76
77
  "@commitlint/config-conventional"
77
78
  ]
79
+ },
80
+ "overrides": {
81
+ "minimist": "^1.2.6"
78
82
  }
79
83
  }