generator-easy-ui5 3.5.1 → 3.5.2

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.
@@ -40,6 +40,11 @@ const generatorOptions = {
40
40
  default: "ui5-community",
41
41
  hide: true, // we don't want to recommend to use this option
42
42
  },
43
+ ghThreshold: {
44
+ type: Number,
45
+ default: 100,
46
+ hide: true, // shouldn't be needed
47
+ },
43
48
  subGeneratorPrefix: {
44
49
  type: String,
45
50
  description: "Prefix used for the lookup of the available generators",
@@ -59,6 +64,18 @@ const generatorOptions = {
59
64
  hide: true, // we don't want to recommend to use this option
60
65
  npmConfig: true,
61
66
  },
67
+ pluginsHome: {
68
+ type: String,
69
+ description: "Home directory of the plugin generators",
70
+ default: path.join(require("os").homedir(), ".npm", "_generator-easy-ui5", "plugin-generators"),
71
+ hide: true, // shouldn't be needed
72
+ npmConfig: true,
73
+ },
74
+ embed: {
75
+ type: Boolean,
76
+ description: "Embeds the selected plugin generator",
77
+ hide: true, // shouldn't be needed
78
+ },
62
79
  list: {
63
80
  type: Boolean,
64
81
  description: "List the available subcommands of the generator",
@@ -151,6 +168,43 @@ module.exports = class extends Generator {
151
168
  }
152
169
  }
153
170
 
171
+ async _npmInstall(dir) {
172
+ return new Promise(
173
+ function (resolve, reject) {
174
+ spawn(hasYarn() ? "yarn" : "npm", ["install", "--no-progress", "--ignore-engines"], {
175
+ stdio: this.config.verbose ? "inherit" : "ignore",
176
+ cwd: dir,
177
+ env: {
178
+ ...process.env,
179
+ NO_UPDATE_NOTIFIER: true,
180
+ },
181
+ })
182
+ .on("exit", function (code) {
183
+ resolve(code);
184
+ })
185
+ .on("error", function (err) {
186
+ reject(err);
187
+ });
188
+ }.bind(this)
189
+ );
190
+ }
191
+
192
+ _unzip(zip, targetPath, zipInternalPath /* used for plugin generators from GitHub (e.g. TS tutorial) */) {
193
+ const zipEntries = zip.getEntries();
194
+ zipEntries.forEach((entry) => {
195
+ const match = !entry.isDirectory && entry.entryName.match(/[^\/]+(\/.+)/);
196
+ let entryPath;
197
+ if (zipInternalPath && match && match[1].startsWith(zipInternalPath)) {
198
+ entryPath = path.dirname(match[1].substring(zipInternalPath.length));
199
+ } else if (!zipInternalPath && match) {
200
+ entryPath = path.dirname(match[1]);
201
+ }
202
+ if (entryPath) {
203
+ zip.extractEntryTo(entry, path.join(targetPath, entryPath), false, true);
204
+ }
205
+ });
206
+ }
207
+
154
208
  async prompting() {
155
209
  const home = path.join(__dirname, "..", "..");
156
210
  const pkgJson = require(path.join(home, "package.json"));
@@ -160,19 +214,14 @@ module.exports = class extends Generator {
160
214
  this.log(yosay(`Welcome to the ${chalk.red("easy-ui5")} ${chalk.yellow(pkgJson.version)} generator!`));
161
215
  }
162
216
 
163
- // check the permissions to Easy UI5s plugin directory which must
164
- // allow read/write to install additional plugin generators
165
- let pluginsHome = path.join(home, "plugin-generators");
166
- try {
167
- fs.accessSync(pluginsHome, fs.constants.R_OK | fs.constants.W_OK);
168
- } catch (e) {
169
- pluginsHome = path.join(require("os").homedir(), ".npm", "_generator-easy-ui5", "plugin-generators");
170
- if (this.options.verbose) {
171
- console.error(`Plugin directory: ${chalk.green(pluginsHome)}`);
172
- console.error(chalk.red(e.message));
173
- }
174
- fs.mkdirSync(pluginsHome, { recursive: true });
217
+ // by default we install the easy-ui5 plugin generators into the following folder:
218
+ // %user_dir%/.npm/_generator-easy-ui5/plugin-generators
219
+ let pluginsHome = this.options.pluginsHome;
220
+ if (this.options.verbose) {
221
+ console.error(`Plugin directory: ${chalk.green(pluginsHome)}`);
222
+ console.error(chalk.red(e.message));
175
223
  }
224
+ fs.mkdirSync(pluginsHome, { recursive: true });
176
225
 
177
226
  // log the plugins and configuration
178
227
  if (this.options.plugins) {
@@ -246,9 +295,11 @@ module.exports = class extends Generator {
246
295
  };
247
296
 
248
297
  // helper to retrieve the available repositories for a GH org
249
- const listGeneratorsForOrg = async (ghOrg, subGeneratorPrefix) => {
298
+ const listGeneratorsForOrg = async (ghOrg, subGeneratorPrefix, threshold) => {
250
299
  const response = await octokit.repos.listForOrg({
251
300
  org: ghOrg,
301
+ sort: "name",
302
+ per_page: threshold,
252
303
  });
253
304
  return filterReposWithSubGeneratorPrefix(response?.data, subGeneratorPrefix);
254
305
  };
@@ -257,6 +308,8 @@ module.exports = class extends Generator {
257
308
  const listGeneratorsForUser = async (ghUser, subGeneratorPrefix) => {
258
309
  const response = await octokit.repos.listForUser({
259
310
  username: ghUser,
311
+ sort: "name",
312
+ per_page: threshold,
260
313
  });
261
314
  return filterReposWithSubGeneratorPrefix(response?.data, subGeneratorPrefix);
262
315
  };
@@ -276,12 +329,14 @@ module.exports = class extends Generator {
276
329
  if (matchGenerator) {
277
330
  // derive and path the generator information from command line
278
331
  const [owner, repo, dir = "/generator", branch] = matchGenerator.slice(1);
332
+ // the plugin path is derived from the owner, repo, dir and branch
333
+ const pluginPath = `_/${owner}/${repo}${dir.replace(/[\/\\]/g, "_")}${branch ? `#${branch.replace(/[\/\\]/g, "_")}` : ""}`;
279
334
  generator = {
280
335
  org: owner,
281
336
  name: repo,
282
337
  branch,
283
338
  dir,
284
- pluginPath: `_/${owner}/${repo}`,
339
+ pluginPath,
285
340
  };
286
341
  // log which generator is being used!
287
342
  if (this.options.verbose) {
@@ -293,6 +348,30 @@ module.exports = class extends Generator {
293
348
  // retrieve the available repositories (if no generator is specified specified directly)
294
349
  let availGenerators;
295
350
  if (!generator) {
351
+ // lookup the non-installed embedded generator(s)
352
+ const generatorsToBeInstalled = glob
353
+ .sync(`${path.join(__dirname, "../../plugins")}/generator-*.zip`)
354
+ .map((file) => {
355
+ const generatorName = path.basename(file, ".zip");
356
+ const generatorPath = path.join(pluginsHome, generatorName);
357
+ return {
358
+ file,
359
+ generatorPath,
360
+ };
361
+ })
362
+ .filter(({ generatorPath }) => !fs.existsSync(generatorPath));
363
+ // install the missing embedded generator(s)
364
+ if (generatorsToBeInstalled.length > 0) {
365
+ this._showBusy(`Installing embedded generators of ${chalk.red("easy-ui5")}...`);
366
+ await Promise.all(
367
+ generatorsToBeInstalled.map(({ file, generatorPath }) => {
368
+ this._unzip(new AdmZip(file), generatorPath);
369
+ return this._npmInstall(generatorPath);
370
+ })
371
+ );
372
+ this._clearBusy(true);
373
+ }
374
+ // offline mode means local generators only versus only mode
296
375
  if (this.options.offline) {
297
376
  availGenerators = glob.sync(`${pluginsHome}/generator-*/package.json`).map((plugin) => {
298
377
  const match = plugin.match(/.*\/(generator-(.+))\/package\.json/);
@@ -304,6 +383,8 @@ module.exports = class extends Generator {
304
383
  };
305
384
  });
306
385
  } else {
386
+ // either lookup the generators from bestofui5.org (next option)
387
+ // or fetch it from the ui5-community gh organization
307
388
  if (this.options.next) {
308
389
  // check bestofui5.org for generators
309
390
  try {
@@ -334,7 +415,7 @@ module.exports = class extends Generator {
334
415
  } else {
335
416
  // check the main GH org for generators
336
417
  try {
337
- availGenerators = await listGeneratorsForOrg(this.options.ghOrg, this.options.subGeneratorPrefix);
418
+ availGenerators = await listGeneratorsForOrg(this.options.ghOrg, this.options.subGeneratorPrefix, this.options.ghThreshold);
338
419
  } catch (e) {
339
420
  console.error(`Failed to connect to GitHub to retrieve all available generators for "${this.options.ghOrg}" organization! Run with --verbose for details!`);
340
421
  if (this.options.verbose) {
@@ -346,14 +427,14 @@ module.exports = class extends Generator {
346
427
  // check the additional GH org for generators with a different prefix
347
428
  try {
348
429
  if (this.options.addGhOrg && this.options.addSubGeneratorPrefix) {
349
- availGenerators = availGenerators.concat(await listGeneratorsForOrg(this.options.addGhOrg, this.options.addSubGeneratorPrefix));
430
+ availGenerators = availGenerators.concat(await listGeneratorsForOrg(this.options.addGhOrg, this.options.addSubGeneratorPrefix, this.options.ghThreshold));
350
431
  }
351
432
  } catch (e) {
352
433
  if (this.options.verbose) {
353
434
  this.log(`Failed to connect to GitHub retrieve additional generators for "${this.options.addGhOrg}" organization! Try to retrieve for user...`);
354
435
  }
355
436
  try {
356
- availGenerators = availGenerators.concat(await listGeneratorsForUser(this.options.addGhOrg, this.options.addSubGeneratorPrefix));
437
+ availGenerators = availGenerators.concat(await listGeneratorsForUser(this.options.addGhOrg, this.options.addSubGeneratorPrefix, this.options.ghThreshold));
357
438
  } catch (e1) {
358
439
  console.error(`Failed to connect to GitHub to retrieve additional generators for organization or user "${this.options.addGhOrg}"! Run with --verbose for details!`);
359
440
  if (this.options.verbose) {
@@ -432,7 +513,7 @@ module.exports = class extends Generator {
432
513
  }
433
514
 
434
515
  if (this.options.verbose) {
435
- this.log(`Using commit ${commitSHA} from @${generator.org}/${generator.name}#${generator.branch}...`);
516
+ this.log(`Using commit ${commitSHA} from @${generator.org}/${generator.name}#${generator.branch}!`);
436
517
  }
437
518
  const shaMarker = path.join(generatorPath, `.${commitSHA}`);
438
519
 
@@ -440,189 +521,189 @@ module.exports = class extends Generator {
440
521
  // check if the SHA marker exists to know whether the generator is up-to-date or not
441
522
  if (this.options.forceUpdate || !fs.existsSync(shaMarker)) {
442
523
  if (this.options.verbose) {
443
- this.log(`Generator "${generator.name}" in "${generatorPath}" is outdated...`);
524
+ this.log(`Generator ${chalk.yellow(generator.name)} in "${generatorPath}" is outdated!`);
444
525
  }
445
526
  // remove if the SHA marker doesn't exist => outdated!
446
- this._showBusy(` Removing old "${generator.name}" templates`);
527
+ this._showBusy(` Removing old ${chalk.yellow(generator.name)} templates...`);
447
528
  await rm(generatorPath, { recursive: true });
448
529
  }
449
530
  }
450
531
 
451
532
  // re-fetch the generator and extract into local plugin folder
452
533
  if (!fs.existsSync(generatorPath)) {
534
+ // unzip the archive
453
535
  if (this.options.verbose) {
454
536
  this.log(`Extracting ZIP to "${generatorPath}"...`);
455
537
  }
456
- this._showBusy(` Downloading and extracting "${generator.name}" templates`);
538
+ this._showBusy(` Downloading ${chalk.yellow(generator.name)} templates...`);
457
539
  const reqZIPArchive = await octokit.repos.downloadZipballArchive({
458
540
  owner: generator.org,
459
541
  repo: generator.name,
460
542
  ref: commitSHA,
461
543
  });
544
+
545
+ this._showBusy(` Extracting ${chalk.yellow(generator.name)} templates...`);
462
546
  const buffer = Buffer.from(new Uint8Array(reqZIPArchive.data));
463
547
  const zip = new AdmZip(buffer);
464
- const zipEntries = zip.getEntries();
465
- zipEntries.forEach((entry) => {
466
- const match = !entry.isDirectory && entry.entryName.match(/[^\/]+(\/.+)/);
467
- let entryPath;
468
- if (generator.dir && match && match[1].startsWith(generator.dir)) {
469
- entryPath = path.dirname(match[1].substring(generator.dir.length));
470
- } else if (!generator.dir && match) {
471
- entryPath = path.dirname(match[1]);
472
- }
473
- if (entryPath) {
474
- zip.extractEntryTo(entry, path.join(generatorPath, entryPath), false, true);
475
- }
476
- });
548
+ this._unzip(zip, generatorPath, generator.dir);
549
+
550
+ // write the sha marker
477
551
  fs.writeFileSync(shaMarker, commitSHA);
478
552
 
479
553
  // run yarn/npm install
480
554
  if (this.options.verbose) {
481
555
  this.log("Installing the plugin dependencies...");
482
556
  }
483
- this._showBusy(` Preparing "${generator.name}"`);
484
- await new Promise(
485
- function (resolve, reject) {
486
- spawn(hasYarn() ? "yarn" : "npm", ["install", "--no-progress", "--ignore-engines"], {
487
- stdio: this.config.verbose ? "inherit" : "ignore",
488
- cwd: generatorPath,
489
- env: {
490
- ...process.env,
491
- NO_UPDATE_NOTIFIER: true,
492
- },
493
- })
494
- .on("exit", function (code) {
495
- resolve(code);
496
- })
497
- .on("error", function (err) {
498
- reject(err);
499
- });
500
- }.bind(this)
501
- );
557
+ this._showBusy(` Preparing ${chalk.yellow(generator.name)}...`);
558
+ await this._npmInstall(generatorPath);
502
559
  }
503
560
 
504
561
  this._clearBusy(true);
505
562
  }
506
563
 
507
- // filter the local options and the help command
508
- const opts = Object.keys(this._options).filter((optionName) => !(generatorOptions.hasOwnProperty(optionName) || optionName === "help"));
564
+ // do not execute the plugin generator during the setup/embed mode
565
+ if (!this.options.embed) {
566
+ // filter the local options and the help command
567
+ const opts = Object.keys(this._options).filter((optionName) => !(generatorOptions.hasOwnProperty(optionName) || optionName === "help"));
509
568
 
510
- // create the env for the plugin generator
511
- let env = this.env; // in case of Yeoman UI the env is injected!
512
- if (!env) {
513
- const yeoman = require("yeoman-environment");
514
- env = yeoman.createEnv(this.args, opts);
515
- }
569
+ // create the env for the plugin generator
570
+ let env = this.env; // in case of Yeoman UI the env is injected!
571
+ if (!env) {
572
+ const yeoman = require("yeoman-environment");
573
+ env = yeoman.createEnv(this.args, opts);
574
+ }
516
575
 
517
- // helper to derive the subcommand
518
- function deriveSubcommand(namespace) {
519
- const match = namespace.match(/[^:]+:(.+)/);
520
- return match ? match[1] : namespace;
521
- }
576
+ // helper to derive the subcommand
577
+ function deriveSubcommand(namespace) {
578
+ const match = namespace.match(/[^:]+:(.+)/);
579
+ return match ? match[1] : namespace;
580
+ }
522
581
 
523
- // filter the hidden subgenerators already
524
- // -> subgenerators must be found in env as they are returned by lookup!
525
- let subGenerators = env.lookup({ localOnly: true, packagePaths: generatorPath }).filter((sub) => {
526
- const subGenerator = env.get(sub.namespace);
527
- return !subGenerator.hidden;
528
- });
582
+ // filter the hidden subgenerators already
583
+ // -> subgenerators must be found in env as they are returned by lookup!
584
+ let subGenerators = env.lookup({ localOnly: true, packagePaths: generatorPath }).filter((sub) => {
585
+ const subGenerator = env.get(sub.namespace);
586
+ return !subGenerator.hidden;
587
+ });
529
588
 
530
- // list the available subgenerators in the console (as help)
531
- if (this.options.list) {
532
- let maxLength = 0;
533
- this.log(
534
- subGenerators
535
- .map((sub) => {
536
- maxLength = Math.max(sub.namespace.length, maxLength);
537
- return sub;
538
- })
539
- .reduce((output, sub) => {
540
- const subGenerator = env.get(sub.namespace);
541
- const displayName = subGenerator.displayName || "";
542
- let line = ` ${deriveSubcommand(sub.namespace).padEnd(maxLength + 2)}`;
543
- if (displayName) {
544
- line += ` # ${subGenerator.displayName}`;
545
- }
546
- return `${output}\n${line}`;
547
- }, `Subcommands (${subGenerators.length}):`)
548
- );
549
- return;
550
- }
589
+ // list the available subgenerators in the console (as help)
590
+ if (this.options.list) {
591
+ let maxLength = 0;
592
+ this.log(
593
+ subGenerators
594
+ .map((sub) => {
595
+ maxLength = Math.max(sub.namespace.length, maxLength);
596
+ return sub;
597
+ })
598
+ .reduce((output, sub) => {
599
+ const subGenerator = env.get(sub.namespace);
600
+ const displayName = subGenerator.displayName || "";
601
+ let line = ` ${deriveSubcommand(sub.namespace).padEnd(maxLength + 2)}`;
602
+ if (displayName) {
603
+ line += ` # ${subGenerator.displayName}`;
604
+ }
605
+ return `${output}\n${line}`;
606
+ }, `Subcommands (${subGenerators.length}):`)
607
+ );
608
+ return;
609
+ }
551
610
 
552
- // if a subcommand is provided as argument, identify the matching subgenerator
553
- // and remove the rest of the subgenerators from the list for later steps
554
- if (this.options.subcommand) {
555
- const selectedSubGenerator = subGenerators.filter((sub) => {
556
- // identify the subgenerator by subcommand
557
- return new RegExp(`:${this.options.subcommand}$`).test(sub.namespace);
558
- });
559
- if (selectedSubGenerator.length == 1) {
560
- subGenerators = selectedSubGenerator;
561
- } else {
562
- this.log(`The generator ${chalk.red(this.options.generator)} has no subcommand ${chalk.red(this.options.subcommand)}. Please select an existing subcommand!`);
611
+ // if a subcommand is provided as argument, identify the matching subgenerator
612
+ // and remove the rest of the subgenerators from the list for later steps
613
+ if (this.options.subcommand) {
614
+ const selectedSubGenerator = subGenerators.filter((sub) => {
615
+ // identify the subgenerator by subcommand
616
+ return new RegExp(`:${this.options.subcommand}$`).test(sub.namespace);
617
+ });
618
+ if (selectedSubGenerator.length == 1) {
619
+ subGenerators = selectedSubGenerator;
620
+ } else {
621
+ this.log(`The generator ${chalk.red(this.options.generator)} has no subcommand ${chalk.red(this.options.subcommand)}. Please select an existing subcommand!`);
622
+ }
563
623
  }
564
- }
565
624
 
566
- // transform the list of the subgenerators and identify the
567
- // default subgenerator for the default selection
568
- let defaultSubGenerator;
569
- let maxLength = 0;
570
- subGenerators = subGenerators
571
- .map((sub) => {
572
- const subGenerator = env.get(sub.namespace);
573
- let subcommand = deriveSubcommand(sub.namespace);
574
- let displayName = subGenerator.displayName || subcommand;
575
- maxLength = Math.max(displayName.length, maxLength);
576
- return {
577
- subcommand,
578
- displayName,
579
- sub,
580
- };
581
- })
582
- .map(({ subcommand, displayName, sub }) => {
583
- const transformed = {
584
- name: `${displayName.padEnd(maxLength + 2)} [${subcommand}]`,
585
- value: sub.namespace,
586
- };
587
- if (/:app$/.test(sub.namespace)) {
588
- defaultSubGenerator = transformed;
625
+ // transform the list of the subgenerators and identify the
626
+ // default subgenerator for the default selection
627
+ let defaultSubGenerator;
628
+ let maxLength = 0;
629
+ subGenerators = subGenerators
630
+ .map((sub) => {
631
+ const subGenerator = env.get(sub.namespace);
632
+ let subcommand = deriveSubcommand(sub.namespace);
633
+ let displayName = subGenerator.displayName || subcommand;
634
+ maxLength = Math.max(displayName.length, maxLength);
635
+ return {
636
+ subcommand,
637
+ displayName,
638
+ sub,
639
+ };
640
+ })
641
+ .map(({ subcommand, displayName, sub }) => {
642
+ const transformed = {
643
+ name: `${displayName.padEnd(maxLength + 2)} [${subcommand}]`,
644
+ value: sub.namespace,
645
+ };
646
+ if (/:app$/.test(sub.namespace)) {
647
+ defaultSubGenerator = transformed;
648
+ }
649
+ return transformed;
650
+ });
651
+
652
+ // at least 1 subgenerator must be present
653
+ if (subGenerators.length >= 1) {
654
+ // by default the 1st subgenerator is used
655
+ let subGenerator = subGenerators[0].value;
656
+
657
+ // if more than 1 subgenerator is present
658
+ // ask the developer to select one!
659
+ if (subGenerators.length > 1) {
660
+ subGenerator = (
661
+ await this.prompt([
662
+ {
663
+ type: "list",
664
+ name: "subGenerator",
665
+ message: "What do you want to do?",
666
+ default: defaultSubGenerator && defaultSubGenerator.value,
667
+ choices: subGenerators,
668
+ },
669
+ ])
670
+ ).subGenerator;
589
671
  }
590
- return transformed;
591
- });
592
672
 
593
- // at least 1 subgenerator must be present
594
- if (subGenerators.length >= 1) {
595
- // by default the 1st subgenerator is used
596
- let subGenerator = subGenerators[0].value;
673
+ if (this.options.verbose) {
674
+ this.log(`Calling ${chalk.red(subGenerator)}...\n \\_ in "${generatorPath}"`);
675
+ }
597
676
 
598
- // if more than 1 subgenerator is present
599
- // ask the developer to select one!
600
- if (subGenerators.length > 1) {
601
- subGenerator = (
602
- await this.prompt([
603
- {
604
- type: "list",
605
- name: "subGenerator",
606
- message: "What do you want to do?",
607
- default: defaultSubGenerator && defaultSubGenerator.value,
608
- choices: subGenerators,
609
- },
610
- ])
611
- ).subGenerator;
677
+ // finally, run the subgenerator
678
+ env.run(subGenerator, {
679
+ verbose: this.options.verbose,
680
+ embedded: true,
681
+ destinationRoot: this.destinationRoot(),
682
+ });
683
+ } else {
684
+ this.log(`The generator ${chalk.red(this.options.generator)} has no visible subgenerators!`);
612
685
  }
613
-
686
+ } else {
687
+ // zip the content of the plugin generator or
688
+ // install the dependencies of the generator
614
689
  if (this.options.verbose) {
615
- this.log(`Calling ${chalk.red(subGenerator)}...\n \\_ in: ${generatorPath}`);
690
+ this.log(`Embedding plugin generator ${chalk.yellow(generator.name)}...`);
691
+ }
692
+ const generatorZIP = new AdmZip();
693
+ const addLocalFile = (file) => {
694
+ const filePath = path.join(generator.name, path.relative(generatorPath, file));
695
+ generatorZIP.addLocalFile(file, path.dirname(filePath), path.basename(filePath));
696
+ if (this.options.verbose) {
697
+ this.log(` + file: ${file}`);
698
+ }
699
+ };
700
+ glob.sync(`${generatorPath}/*`, { nodir: true, dot: true }).forEach(addLocalFile);
701
+ glob.sync(`${generatorPath}/!(node_modules)/**/*`, { nodir: true, dot: true }).forEach(addLocalFile);
702
+ const generatorZIPPath = path.join(__dirname, "../../plugins", `${generator.name}.zip`);
703
+ generatorZIP.writeZip(generatorZIPPath);
704
+ if (this.options.verbose) {
705
+ this.log(`Stored plugin generator ${chalk.yellow(generator.name)} zip to "${generatorZIPPath}"!`);
616
706
  }
617
-
618
- // finally, run the subgenerator
619
- env.run(subGenerator, {
620
- verbose: this.options.verbose,
621
- embedded: true,
622
- destinationRoot: this.destinationRoot(),
623
- });
624
- } else {
625
- this.log(`The generator ${chalk.red(this.options.generator)} has no visible subgenerators!`);
626
707
  }
627
708
  }
628
709
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "generator-easy-ui5",
3
- "version": "3.5.1",
3
+ "version": "3.5.2",
4
4
  "description": "Generator for UI5-based project",
5
5
  "main": "generators/app/index.js",
6
6
  "files": [
@@ -10,7 +10,7 @@
10
10
  "node": ">=14.0.0"
11
11
  },
12
12
  "scripts": {
13
- "postinstall": "node generators/app/postinstall",
13
+ "prepublishOnly": "npx yo ./ project --embed",
14
14
  "start": "yo easy-ui5 project",
15
15
  "test": "mocha",
16
16
  "test:subgen:list": "yo easy-ui5 project --list",
@@ -1,143 +0,0 @@
1
- "use strict";
2
- const spawn = require("cross-spawn");
3
- const fs = require("fs");
4
- const { rm } = require("fs").promises;
5
- const path = require("path");
6
- const { hasYarn } = require("yarn-or-npm");
7
- const { Octokit } = require("@octokit/rest");
8
- const { throttling } = require("@octokit/plugin-throttling");
9
- const MyOctokit = Octokit.plugin(throttling);
10
- const AdmZip = require("adm-zip");
11
-
12
- // helper to retrieve config entries from npm
13
- // --> npm config set easy-ui5_addGhOrg XYZ
14
- const NPM_CONFIG_PREFIX = "easy-ui5_";
15
- let npmConfig;
16
- const getNPMConfig = (configName) => {
17
- if (!npmConfig) {
18
- npmConfig = require("libnpmconfig").read();
19
- }
20
- return npmConfig && npmConfig[`${NPM_CONFIG_PREFIX}${configName}`];
21
- };
22
-
23
- const ghOrg = "ui5-community",
24
- repoName = "generator-ui5-project",
25
- branch = "main",
26
- ghAuthToken = getNPMConfig("ghAuthToken");
27
-
28
- (async () => {
29
- let _busy;
30
-
31
- function showBusy(statusText) {
32
- clearBusy();
33
- const progressChars = ["\\", "|", "/", "-"];
34
- let i = 0;
35
- process.stdout.write(`\r${statusText} `);
36
- _busy = {
37
- text: statusText,
38
- timer: setInterval(() => {
39
- process.stdout.write(`\r${statusText} ${progressChars[i++]}`);
40
- i %= progressChars.length;
41
- }, 250),
42
- };
43
- }
44
-
45
- function clearBusy(newLine) {
46
- if (_busy) {
47
- clearInterval(_busy.timer);
48
- process.stdout.write("\r".padEnd(_busy.text.length + 3) + (newLine ? "\n" : ""));
49
- _busy = null;
50
- }
51
- }
52
-
53
- const pkg = require(path.join(__dirname, "../../package.json"));
54
- console.log(`${pkg.name}:${pkg.version} - ${ghAuthToken}`);
55
- const octokit = new MyOctokit({
56
- userAgent: `${pkg.name}:${pkg.version}`,
57
- auth: ghAuthToken,
58
- throttle: {
59
- onRateLimit: (retryAfter, options) => {
60
- console.log("Hit the GitHub API limit! Request quota exhausted for this request.");
61
- if (options.request.retryCount === 0) {
62
- // only retries once
63
- this.log(`Retrying after ${retryAfter} seconds. Alternatively, you can cancel this operation and supply an auth token with "npm config set easy-ui5_ghAuthToken ghp_xxxx".`);
64
- return true;
65
- }
66
- },
67
- onAbuseLimit: () => {
68
- // does not retry, only logs a warning
69
- console.error('Hit the GitHub API limit again! Please supply an auth token with with "npm config set easy-ui5_ghAuthToken ghp_xxxx".');
70
- },
71
- },
72
- });
73
-
74
- const reqBranch = await octokit.repos.getBranch({
75
- owner: ghOrg,
76
- repo: repoName,
77
- branch,
78
- });
79
-
80
- const commitSHA = reqBranch.data.commit.sha;
81
-
82
- // eslint-disable-next-line
83
- console.log(`Using commit ${commitSHA} from @${ghOrg}/${repoName}#${branch}...`);
84
- const generatorPath = path.join(__dirname, "../../plugin-generators", repoName);
85
- const shaMarker = path.join(generatorPath, `.${commitSHA}`);
86
-
87
- if (fs.existsSync(generatorPath)) {
88
- // check if the SHA marker exists to know whether the generator is up-to-date or not
89
- if (!fs.existsSync(shaMarker)) {
90
- // eslint-disable-next-line
91
- console.log(`Fetching new ZIP as the default generator is outdated...`);
92
- // remove if the SHA marker doesn't exist => outdated!
93
- showBusy(" Removing old default templates");
94
- await rm(generatorPath, { recursive: true });
95
- }
96
- }
97
-
98
- // re-fetch the generator and extract into local plugin folder
99
- if (!fs.existsSync(generatorPath)) {
100
- console.log("Extracting default templates...");
101
- showBusy(" Downloading and extracting default templates");
102
- const reqZIPArchive = await octokit.repos.downloadZipballArchive({
103
- owner: ghOrg,
104
- repo: repoName,
105
- ref: commitSHA,
106
- });
107
- const buffer = Buffer.from(new Uint8Array(reqZIPArchive.data));
108
- const zip = new AdmZip(buffer);
109
- const zipEntries = zip.getEntries();
110
- zipEntries.forEach((entry) => {
111
- const match = !entry.isDirectory && entry.entryName.match(/[^\/]+\/(.+)/);
112
- if (match) {
113
- const entryPath = match[1].slice(0, entry.name.length * -1);
114
- zip.extractEntryTo(entry, path.join(generatorPath, entryPath), false, true);
115
- }
116
- });
117
- fs.writeFileSync(shaMarker, commitSHA);
118
-
119
- // run yarn/npm install
120
- console.log("Installing the plugin dependencies...");
121
- showBusy(" Preparing the default templates");
122
- await new Promise(
123
- function (resolve, reject) {
124
- spawn(hasYarn() ? "yarn" : "npm", ["install", "--no-progress", "--ignore-engines"], {
125
- stdio: "inherit",
126
- cwd: generatorPath,
127
- env: {
128
- ...process.env,
129
- NO_UPDATE_NOTIFIER: true,
130
- },
131
- })
132
- .on("exit", function (code) {
133
- resolve(code);
134
- })
135
- .on("error", function (err) {
136
- reject(err);
137
- });
138
- }.bind(this)
139
- );
140
- }
141
-
142
- clearBusy(true);
143
- })();