@gadmin2n/cli 0.0.111 → 0.0.112
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/actions/new.action.js +30 -0
- package/actions/update.action.js +119 -66
- package/lib/executable-paths.d.ts +27 -0
- package/lib/executable-paths.js +55 -0
- package/lib/schematics-root.d.ts +20 -0
- package/lib/schematics-root.js +51 -0
- package/package.json +1 -1
package/actions/new.action.js
CHANGED
|
@@ -25,6 +25,10 @@ const schematics_1 = require("../lib/schematics");
|
|
|
25
25
|
const ui_1 = require("../lib/ui");
|
|
26
26
|
const formatting_1 = require("../lib/utils/formatting");
|
|
27
27
|
const abstract_action_1 = require("./abstract.action");
|
|
28
|
+
const schematics_root_1 = require("../lib/schematics-root");
|
|
29
|
+
const base_store_1 = require("../lib/template-merge/base-store");
|
|
30
|
+
const types_1 = require("../lib/template-merge/types");
|
|
31
|
+
const executable_paths_1 = require("../lib/executable-paths");
|
|
28
32
|
class NewAction extends abstract_action_1.AbstractAction {
|
|
29
33
|
handle(inputs, options) {
|
|
30
34
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -42,6 +46,32 @@ class NewAction extends abstract_action_1.AbstractAction {
|
|
|
42
46
|
yield applyEnvConfig(projectDirectory, options).catch((err) => {
|
|
43
47
|
console.error(chalk.yellow(`[warn] Failed to apply env config: ${err && err.message ? err.message : err}`));
|
|
44
48
|
});
|
|
49
|
+
// Pin the 3-way merge base at project init time. Recording the exact
|
|
50
|
+
// schematics version that scaffolded this project means the FIRST
|
|
51
|
+
// `gadmin2 update` can immediately do a real 3-way merge — no
|
|
52
|
+
// bootstrap-then-rerun dance. Failure is non-fatal: if meta can't be
|
|
53
|
+
// written here, `gadmin2 update` still has its bootstrap fallback.
|
|
54
|
+
try {
|
|
55
|
+
const projectAbsDir = (0, path_1.join)(process.cwd(), projectDirectory);
|
|
56
|
+
const schematicsVersion = (0, schematics_root_1.getSchematicsVersion)();
|
|
57
|
+
(0, base_store_1.writeMeta)(projectAbsDir, {
|
|
58
|
+
schematicsVersion,
|
|
59
|
+
schemaVersion: types_1.CURRENT_META_SCHEMA_VERSION,
|
|
60
|
+
});
|
|
61
|
+
(0, base_store_1.writeReadme)(projectAbsDir);
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
console.warn(chalk.yellow(`[warn] Failed to write .gadmin/.meta.json (first \`gadmin2 update\` will bootstrap instead): ${err && err.message ? err.message : err}`));
|
|
65
|
+
}
|
|
66
|
+
// @angular-devkit/schematics drops the source mode bits when writing
|
|
67
|
+
// generated files, so executable scripts (compose-ctl.sh, etc.) come
|
|
68
|
+
// out as 0644. Re-apply +x for known entry points.
|
|
69
|
+
try {
|
|
70
|
+
(0, executable_paths_1.ensureExecutableBits)((0, path_1.join)(process.cwd(), projectDirectory));
|
|
71
|
+
}
|
|
72
|
+
catch (_a) {
|
|
73
|
+
// best-effort, never fatal
|
|
74
|
+
}
|
|
45
75
|
}
|
|
46
76
|
if (!shouldSkipInstall) {
|
|
47
77
|
console.info('Begin to install server dependence ...');
|
package/actions/update.action.js
CHANGED
|
@@ -19,6 +19,8 @@ const child_process_1 = require("child_process");
|
|
|
19
19
|
const abstract_action_1 = require("./abstract.action");
|
|
20
20
|
const self_update_action_1 = require("./self-update.action");
|
|
21
21
|
const version_check_1 = require("../lib/version-check");
|
|
22
|
+
const schematics_root_1 = require("../lib/schematics-root");
|
|
23
|
+
const executable_paths_1 = require("../lib/executable-paths");
|
|
22
24
|
const merge3way_1 = require("../lib/template-merge/merge3way");
|
|
23
25
|
const binary_detect_1 = require("../lib/template-merge/binary-detect");
|
|
24
26
|
const residual_scan_1 = require("../lib/template-merge/residual-scan");
|
|
@@ -49,38 +51,8 @@ function formatMaterializeError(schematicsVersion, err) {
|
|
|
49
51
|
/* ------------------------------------------------------------------ *
|
|
50
52
|
* Template config / path resolution
|
|
51
53
|
* ------------------------------------------------------------------ */
|
|
52
|
-
/**
|
|
53
|
-
* Locate the @gadmin2n/schematics install root, searching:
|
|
54
|
-
* 1. the instance project dir
|
|
55
|
-
* 2. the instance project's server/ subdir (where deps usually live)
|
|
56
|
-
* 3. the CLI's own node_modules (covers globally installed CLI where
|
|
57
|
-
* schematics ships alongside @gadmin2n/cli but is NOT installed in
|
|
58
|
-
* the user's project)
|
|
59
|
-
* Throws a helpful error if none of these resolve.
|
|
60
|
-
*/
|
|
61
|
-
function findSchematicsRoot(instanceDir = process.cwd()) {
|
|
62
|
-
const searchPaths = [
|
|
63
|
-
instanceDir,
|
|
64
|
-
path.join(instanceDir, 'server'),
|
|
65
|
-
path.resolve(__dirname, '..'),
|
|
66
|
-
];
|
|
67
|
-
for (const searchPath of searchPaths) {
|
|
68
|
-
try {
|
|
69
|
-
const pkgPath = require.resolve('@gadmin2n/schematics/package.json', {
|
|
70
|
-
paths: [searchPath],
|
|
71
|
-
});
|
|
72
|
-
return path.dirname(pkgPath);
|
|
73
|
-
}
|
|
74
|
-
catch (_a) {
|
|
75
|
-
// continue
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
throw new Error('Cannot resolve @gadmin2n/schematics package. ' +
|
|
79
|
-
'Make sure it is installed globally (alongside @gadmin2n/cli) ' +
|
|
80
|
-
'or as a dependency of the project.');
|
|
81
|
-
}
|
|
82
54
|
function resolveTemplatePath(templateName) {
|
|
83
|
-
const schematicsRoot = findSchematicsRoot();
|
|
55
|
+
const schematicsRoot = (0, schematics_root_1.findSchematicsRoot)();
|
|
84
56
|
const nameVariants = [templateName];
|
|
85
57
|
if (templateName.startsWith('gadmin2n-')) {
|
|
86
58
|
nameVariants.push(templateName.replace('gadmin2n-', 'gadmin2-'));
|
|
@@ -584,19 +556,79 @@ function applyPlan(plan, baseRoot, oursRoot, theirsRoot, opts) {
|
|
|
584
556
|
/* ------------------------------------------------------------------ *
|
|
585
557
|
* Print summary
|
|
586
558
|
* ------------------------------------------------------------------ */
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
559
|
+
/**
|
|
560
|
+
* Unified file-list printer for a `ClassifiedPlan`. Used by both pre-apply
|
|
561
|
+
* preview / dry-run output AND post-apply summary so the wording stays
|
|
562
|
+
* consistent across the three call sites.
|
|
563
|
+
*
|
|
564
|
+
* Sections that have zero files are skipped entirely (no "0 files added"
|
|
565
|
+
* noise). Structural conflicts (add/add, modify/delete, delete/modify) are
|
|
566
|
+
* shown together because they're all "needs decision" situations the user
|
|
567
|
+
* should see before applying.
|
|
568
|
+
*
|
|
569
|
+
* The "kept" footer (`plan.keep + plan.noop`) is shown by default; pass
|
|
570
|
+
* `{ showKept: false }` to suppress it.
|
|
571
|
+
*/
|
|
572
|
+
function printPlanFileLists(plan, opts) {
|
|
573
|
+
var _a;
|
|
574
|
+
const showKept = (_a = opts === null || opts === void 0 ? void 0 : opts.showKept) !== null && _a !== void 0 ? _a : true;
|
|
575
|
+
const plural = (n) => (n === 1 ? '' : 's');
|
|
576
|
+
if (plan.update.length > 0) {
|
|
577
|
+
console.info(chalk.yellow(`📝 Updated (3-way merged) — ${plan.update.length} file${plural(plan.update.length)}`));
|
|
578
|
+
for (const f of plan.update)
|
|
579
|
+
console.info(` ${f}`);
|
|
580
|
+
console.info();
|
|
581
|
+
}
|
|
582
|
+
if (plan.add.length > 0) {
|
|
583
|
+
console.info(chalk.green(`➕ Added (template-only) — ${plan.add.length} file${plural(plan.add.length)}`));
|
|
584
|
+
for (const f of plan.add)
|
|
585
|
+
console.info(` ${f}`);
|
|
586
|
+
console.info();
|
|
587
|
+
}
|
|
588
|
+
if (plan.delete.length > 0) {
|
|
589
|
+
console.info(chalk.red(`🗑 Deleted (template removed) — ${plan.delete.length} file${plural(plan.delete.length)}`));
|
|
590
|
+
for (const f of plan.delete)
|
|
591
|
+
console.info(` ${f}`);
|
|
592
|
+
console.info();
|
|
593
|
+
}
|
|
594
|
+
const structural = [
|
|
595
|
+
...plan.addAddConflict.map((p) => ['add/add', p]),
|
|
596
|
+
...plan.modifyDeleteConflict.map((p) => ['modify/delete', p]),
|
|
597
|
+
...plan.deleteModifyConflict.map((p) => ['delete/modify', p]),
|
|
598
|
+
];
|
|
599
|
+
if (structural.length > 0) {
|
|
600
|
+
console.info(chalk.magenta(`⚠️ Structural conflicts — ${structural.length} file${plural(structural.length)}`));
|
|
601
|
+
const padKind = (k) => k.padEnd(16);
|
|
602
|
+
for (const [kind, p] of structural) {
|
|
603
|
+
console.info(` ${chalk.magenta(padKind(`[${kind}]`))} ${p}`);
|
|
604
|
+
}
|
|
605
|
+
console.info();
|
|
606
|
+
}
|
|
607
|
+
if (showKept) {
|
|
608
|
+
const keptCount = plan.keep.length + plan.noop.length;
|
|
609
|
+
if (keptCount > 0) {
|
|
610
|
+
console.info(chalk.gray(` ${keptCount} file${plural(keptCount)} kept (instance-only or identical)`));
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
/**
|
|
615
|
+
* Print post-apply conflict records (output of `applyPlan`). These differ
|
|
616
|
+
* from a `ClassifiedPlan` because they include `kind: 'content' | 'binary'`
|
|
617
|
+
* which is only known after the merge actually runs.
|
|
618
|
+
*/
|
|
619
|
+
function printConflictRecords(conflicts) {
|
|
620
|
+
const padKind = (k) => k.padEnd(16);
|
|
621
|
+
for (const c of conflicts) {
|
|
622
|
+
const kindLabel = `[${c.kind}]`;
|
|
623
|
+
console.info(` ${chalk.yellow(padKind(kindLabel))} ${c.path}` +
|
|
624
|
+
(c.detail ? chalk.gray(` (${c.detail})`) : ''));
|
|
593
625
|
}
|
|
594
626
|
}
|
|
595
627
|
function printSummary(plan, conflicts, templateName, schematicsVersion) {
|
|
596
628
|
console.info(chalk.bold('\n═══════════════════════════════════════════════════'));
|
|
597
629
|
console.info(chalk.bold(' Template Update Summary'));
|
|
598
630
|
console.info(chalk.bold('═══════════════════════════════════════════════════\n'));
|
|
599
|
-
|
|
631
|
+
printPlanFileLists(plan);
|
|
600
632
|
console.info();
|
|
601
633
|
if (conflicts.length === 0) {
|
|
602
634
|
console.info(chalk.green('✅ Template update complete — no conflicts.'));
|
|
@@ -604,12 +636,7 @@ function printSummary(plan, conflicts, templateName, schematicsVersion) {
|
|
|
604
636
|
return;
|
|
605
637
|
}
|
|
606
638
|
console.info(chalk.yellow(`⚠️ ${conflicts.length} conflict(s) need your attention:\n`));
|
|
607
|
-
|
|
608
|
-
for (const c of conflicts) {
|
|
609
|
-
const kindLabel = `[${c.kind}]`;
|
|
610
|
-
console.info(` ${chalk.yellow(padKind(kindLabel))} ${c.path}` +
|
|
611
|
-
(c.detail ? chalk.gray(` (${c.detail})`) : ''));
|
|
612
|
-
}
|
|
639
|
+
printConflictRecords(conflicts);
|
|
613
640
|
console.info();
|
|
614
641
|
console.info(chalk.gray(' Recommended workflow:'));
|
|
615
642
|
console.info(chalk.gray(' $ git status # see all modified files'));
|
|
@@ -955,9 +982,7 @@ class UpdateAction extends abstract_action_1.AbstractAction {
|
|
|
955
982
|
snapshotPackageJson(path.join(instanceDir, 'web'), 'web'),
|
|
956
983
|
snapshotPackageJson(path.join(instanceDir, 'server'), 'server'),
|
|
957
984
|
];
|
|
958
|
-
const
|
|
959
|
-
const schematicsPkg = require(path.join(schematicsRoot, 'package.json'));
|
|
960
|
-
const schematicsVersion = schematicsPkg.version || '0.0.0';
|
|
985
|
+
const schematicsVersion = (0, schematics_root_1.getSchematicsVersion)(instanceDir);
|
|
961
986
|
// First-time bootstrap: meta absent → write meta + README, exit.
|
|
962
987
|
if (!fs.existsSync((0, base_store_1.metaPath)(instanceDir))) {
|
|
963
988
|
if (dryRun) {
|
|
@@ -1006,28 +1031,56 @@ class UpdateAction extends abstract_action_1.AbstractAction {
|
|
|
1006
1031
|
console.info(chalk.bold('═══════════════════════════════════════════════════'));
|
|
1007
1032
|
console.info(chalk.bold(' Template Update Plan (dry-run)'));
|
|
1008
1033
|
console.info(chalk.bold('═══════════════════════════════════════════════════\n'));
|
|
1009
|
-
|
|
1010
|
-
console.info(chalk.green(` add ${f}`));
|
|
1011
|
-
for (const f of plan.delete)
|
|
1012
|
-
console.info(chalk.red(` delete ${f}`));
|
|
1013
|
-
for (const f of plan.update)
|
|
1014
|
-
console.info(chalk.yellow(` update ${f}`));
|
|
1015
|
-
for (const f of plan.addAddConflict)
|
|
1016
|
-
console.info(chalk.magenta(` add/add ${f}`));
|
|
1017
|
-
for (const f of plan.modifyDeleteConflict)
|
|
1018
|
-
console.info(chalk.magenta(` modify/delete ${f}`));
|
|
1019
|
-
for (const f of plan.deleteModifyConflict)
|
|
1020
|
-
console.info(chalk.magenta(` delete/modify ${f}`));
|
|
1034
|
+
printPlanFileLists(plan);
|
|
1021
1035
|
console.info();
|
|
1022
1036
|
}
|
|
1023
1037
|
else {
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1038
|
+
// Pre-apply preview + confirm (skipped under --yes).
|
|
1039
|
+
const applyAndReport = () => {
|
|
1040
|
+
const conflicts = applyPlan(plan, baseRoot, instanceDir, theirsRoot, mergeOpts);
|
|
1041
|
+
// Always advance meta to new version, even when conflicts present (invariant #2).
|
|
1042
|
+
(0, base_store_1.writeMeta)(instanceDir, {
|
|
1043
|
+
schematicsVersion,
|
|
1044
|
+
schemaVersion: types_1.CURRENT_META_SCHEMA_VERSION,
|
|
1045
|
+
});
|
|
1046
|
+
// Re-apply +x to known script entry points: applyPlan uses
|
|
1047
|
+
// fs.copyFileSync for newly-added files, which does not preserve
|
|
1048
|
+
// the source template's mode bits.
|
|
1049
|
+
try {
|
|
1050
|
+
(0, executable_paths_1.ensureExecutableBits)(instanceDir);
|
|
1051
|
+
}
|
|
1052
|
+
catch (_a) {
|
|
1053
|
+
// best-effort, never fatal
|
|
1054
|
+
}
|
|
1055
|
+
printSummary(plan, conflicts, templateName, schematicsVersion);
|
|
1056
|
+
};
|
|
1057
|
+
if (autoYes) {
|
|
1058
|
+
applyAndReport();
|
|
1059
|
+
}
|
|
1060
|
+
else {
|
|
1061
|
+
console.info(chalk.bold('\n═══════════════════════════════════════════════════'));
|
|
1062
|
+
console.info(chalk.bold(' Template Update Preview'));
|
|
1063
|
+
console.info(chalk.bold('═══════════════════════════════════════════════════\n'));
|
|
1064
|
+
printPlanFileLists(plan);
|
|
1065
|
+
console.info();
|
|
1066
|
+
const { proceedTemplate } = yield inquirer.prompt([
|
|
1067
|
+
{
|
|
1068
|
+
type: 'confirm',
|
|
1069
|
+
name: 'proceedTemplate',
|
|
1070
|
+
message: 'Apply this template update to your instance?',
|
|
1071
|
+
default: true,
|
|
1072
|
+
},
|
|
1073
|
+
]);
|
|
1074
|
+
if (proceedTemplate) {
|
|
1075
|
+
applyAndReport();
|
|
1076
|
+
}
|
|
1077
|
+
else {
|
|
1078
|
+
console.info(chalk.gray('\nTemplate update skipped — base & files unchanged.\n'));
|
|
1079
|
+
// Fall through to stage 2 (.claude sync) and stage 3 (install).
|
|
1080
|
+
// pkgSnapshots are already captured but package.json is unchanged,
|
|
1081
|
+
// so maybeInstallChangedDeps will naturally find no diff and skip.
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1031
1084
|
}
|
|
1032
1085
|
}
|
|
1033
1086
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Files (relative to instance / project root) that must carry the executable
|
|
3
|
+
* bit. Both `gadmin2 n` and `gadmin2 update` re-apply this set after writing
|
|
4
|
+
* files because:
|
|
5
|
+
*
|
|
6
|
+
* - @angular-devkit/schematics writes generated files via fs.writeFile, which
|
|
7
|
+
* does NOT preserve the source template's mode.
|
|
8
|
+
* - update.action's applyPlan uses fs.copyFileSync for "added" files, which
|
|
9
|
+
* also does not preserve mode.
|
|
10
|
+
*
|
|
11
|
+
* Without this step the user has to `chmod +x compose-ctl.sh` manually after
|
|
12
|
+
* every `gadmin2 n` / `gadmin2 update`.
|
|
13
|
+
*
|
|
14
|
+
* KEEP IN SYNC with the schematics templates: any new shell entry point added
|
|
15
|
+
* to schematics that the user is expected to invoke directly should be listed
|
|
16
|
+
* here too.
|
|
17
|
+
*/
|
|
18
|
+
export declare const EXECUTABLE_PATHS: ReadonlyArray<string>;
|
|
19
|
+
/**
|
|
20
|
+
* Best-effort: add the executable bit to known script entry points under
|
|
21
|
+
* `projectDir`. Only files that actually exist are touched. Failures are
|
|
22
|
+
* silently swallowed — chmod is a no-op on Windows and in containers without
|
|
23
|
+
* permission, but neither is a reason to abort the broader command.
|
|
24
|
+
*
|
|
25
|
+
* Returns the list of paths that were updated, suitable for verbose logging.
|
|
26
|
+
*/
|
|
27
|
+
export declare function ensureExecutableBits(projectDir: string): string[];
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ensureExecutableBits = exports.EXECUTABLE_PATHS = void 0;
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const path = require("path");
|
|
6
|
+
/**
|
|
7
|
+
* Files (relative to instance / project root) that must carry the executable
|
|
8
|
+
* bit. Both `gadmin2 n` and `gadmin2 update` re-apply this set after writing
|
|
9
|
+
* files because:
|
|
10
|
+
*
|
|
11
|
+
* - @angular-devkit/schematics writes generated files via fs.writeFile, which
|
|
12
|
+
* does NOT preserve the source template's mode.
|
|
13
|
+
* - update.action's applyPlan uses fs.copyFileSync for "added" files, which
|
|
14
|
+
* also does not preserve mode.
|
|
15
|
+
*
|
|
16
|
+
* Without this step the user has to `chmod +x compose-ctl.sh` manually after
|
|
17
|
+
* every `gadmin2 n` / `gadmin2 update`.
|
|
18
|
+
*
|
|
19
|
+
* KEEP IN SYNC with the schematics templates: any new shell entry point added
|
|
20
|
+
* to schematics that the user is expected to invoke directly should be listed
|
|
21
|
+
* here too.
|
|
22
|
+
*/
|
|
23
|
+
exports.EXECUTABLE_PATHS = [
|
|
24
|
+
'compose-ctl.sh',
|
|
25
|
+
'server/start-prod.sh',
|
|
26
|
+
];
|
|
27
|
+
/**
|
|
28
|
+
* Best-effort: add the executable bit to known script entry points under
|
|
29
|
+
* `projectDir`. Only files that actually exist are touched. Failures are
|
|
30
|
+
* silently swallowed — chmod is a no-op on Windows and in containers without
|
|
31
|
+
* permission, but neither is a reason to abort the broader command.
|
|
32
|
+
*
|
|
33
|
+
* Returns the list of paths that were updated, suitable for verbose logging.
|
|
34
|
+
*/
|
|
35
|
+
function ensureExecutableBits(projectDir) {
|
|
36
|
+
const updated = [];
|
|
37
|
+
for (const rel of exports.EXECUTABLE_PATHS) {
|
|
38
|
+
const abs = path.join(projectDir, rel);
|
|
39
|
+
if (!fs.existsSync(abs))
|
|
40
|
+
continue;
|
|
41
|
+
try {
|
|
42
|
+
const cur = fs.statSync(abs).mode;
|
|
43
|
+
const next = cur | 0o111; // owner+group+other +x
|
|
44
|
+
if (next !== cur) {
|
|
45
|
+
fs.chmodSync(abs, next);
|
|
46
|
+
updated.push(rel);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
catch (_a) {
|
|
50
|
+
// ignore — Windows / restricted FS
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return updated;
|
|
54
|
+
}
|
|
55
|
+
exports.ensureExecutableBits = ensureExecutableBits;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Locate the @gadmin2n/schematics install root, searching:
|
|
3
|
+
* 1. the supplied instance dir (defaults to process.cwd())
|
|
4
|
+
* 2. <instanceDir>/server (where deps are usually hoisted)
|
|
5
|
+
* 3. the CLI's own node_modules — covers globally installed CLI where
|
|
6
|
+
* schematics ships alongside @gadmin2n/cli but is NOT installed in
|
|
7
|
+
* the user's project.
|
|
8
|
+
*
|
|
9
|
+
* Throws a helpful error if none of these resolve.
|
|
10
|
+
*
|
|
11
|
+
* Used by:
|
|
12
|
+
* - update.action (resolveTemplatePath, schematics version pin)
|
|
13
|
+
* - new.action (meta bootstrap at project init)
|
|
14
|
+
*/
|
|
15
|
+
export declare function findSchematicsRoot(instanceDir?: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* Convenience wrapper: returns the version field of @gadmin2n/schematics's
|
|
18
|
+
* package.json. Falls back to '0.0.0' if the field is missing.
|
|
19
|
+
*/
|
|
20
|
+
export declare function getSchematicsVersion(instanceDir?: string): string;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getSchematicsVersion = exports.findSchematicsRoot = void 0;
|
|
4
|
+
const path = require("path");
|
|
5
|
+
/**
|
|
6
|
+
* Locate the @gadmin2n/schematics install root, searching:
|
|
7
|
+
* 1. the supplied instance dir (defaults to process.cwd())
|
|
8
|
+
* 2. <instanceDir>/server (where deps are usually hoisted)
|
|
9
|
+
* 3. the CLI's own node_modules — covers globally installed CLI where
|
|
10
|
+
* schematics ships alongside @gadmin2n/cli but is NOT installed in
|
|
11
|
+
* the user's project.
|
|
12
|
+
*
|
|
13
|
+
* Throws a helpful error if none of these resolve.
|
|
14
|
+
*
|
|
15
|
+
* Used by:
|
|
16
|
+
* - update.action (resolveTemplatePath, schematics version pin)
|
|
17
|
+
* - new.action (meta bootstrap at project init)
|
|
18
|
+
*/
|
|
19
|
+
function findSchematicsRoot(instanceDir = process.cwd()) {
|
|
20
|
+
const searchPaths = [
|
|
21
|
+
instanceDir,
|
|
22
|
+
path.join(instanceDir, 'server'),
|
|
23
|
+
path.resolve(__dirname, '..'),
|
|
24
|
+
];
|
|
25
|
+
for (const searchPath of searchPaths) {
|
|
26
|
+
try {
|
|
27
|
+
const pkgPath = require.resolve('@gadmin2n/schematics/package.json', {
|
|
28
|
+
paths: [searchPath],
|
|
29
|
+
});
|
|
30
|
+
return path.dirname(pkgPath);
|
|
31
|
+
}
|
|
32
|
+
catch (_a) {
|
|
33
|
+
// continue
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
throw new Error('Cannot resolve @gadmin2n/schematics package. ' +
|
|
37
|
+
'Make sure it is installed globally (alongside @gadmin2n/cli) ' +
|
|
38
|
+
'or as a dependency of the project.');
|
|
39
|
+
}
|
|
40
|
+
exports.findSchematicsRoot = findSchematicsRoot;
|
|
41
|
+
/**
|
|
42
|
+
* Convenience wrapper: returns the version field of @gadmin2n/schematics's
|
|
43
|
+
* package.json. Falls back to '0.0.0' if the field is missing.
|
|
44
|
+
*/
|
|
45
|
+
function getSchematicsVersion(instanceDir) {
|
|
46
|
+
const root = findSchematicsRoot(instanceDir);
|
|
47
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
48
|
+
const pkg = require(path.join(root, 'package.json'));
|
|
49
|
+
return (pkg && pkg.version) || '0.0.0';
|
|
50
|
+
}
|
|
51
|
+
exports.getSchematicsVersion = getSchematicsVersion;
|