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.
- package/generators/app/index.js +240 -159
- package/package.json +2 -2
- package/generators/app/postinstall.js +0 -143
package/generators/app/index.js
CHANGED
|
@@ -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
|
-
//
|
|
164
|
-
//
|
|
165
|
-
let pluginsHome =
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
465
|
-
|
|
466
|
-
|
|
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
|
|
484
|
-
await
|
|
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
|
-
//
|
|
508
|
-
|
|
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
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
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
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
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
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
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
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
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
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
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
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
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
|
-
|
|
594
|
-
|
|
595
|
-
|
|
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
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
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(`
|
|
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.
|
|
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
|
-
"
|
|
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
|
-
})();
|