@zenithbuild/cli 0.6.2 → 0.6.4
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/dist/build.js +972 -85
- package/dist/index.js +9 -0
- package/dist/toolchain-paths.js +110 -0
- package/dist/version-check.js +378 -0
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -116,6 +116,15 @@ export async function cli(args, cwd) {
|
|
|
116
116
|
const outDir = join(projectRoot, 'dist');
|
|
117
117
|
const config = await loadConfig(projectRoot);
|
|
118
118
|
|
|
119
|
+
if (command === 'build' || command === 'dev') {
|
|
120
|
+
const { maybeWarnAboutZenithVersionMismatch } = await import('./version-check.js');
|
|
121
|
+
await maybeWarnAboutZenithVersionMismatch({
|
|
122
|
+
projectRoot,
|
|
123
|
+
logger,
|
|
124
|
+
command
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
119
128
|
if (command === 'build') {
|
|
120
129
|
const { build } = await import('./build.js');
|
|
121
130
|
logger.build('Building…');
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
|
+
import { dirname, resolve } from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
|
|
6
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
7
|
+
const __dirname = dirname(__filename);
|
|
8
|
+
const CLI_ROOT = resolve(__dirname, '..');
|
|
9
|
+
const localRequire = createRequire(import.meta.url);
|
|
10
|
+
|
|
11
|
+
function safeCreateRequire(projectRoot) {
|
|
12
|
+
if (!projectRoot) {
|
|
13
|
+
return localRequire;
|
|
14
|
+
}
|
|
15
|
+
try {
|
|
16
|
+
return createRequire(resolve(projectRoot, 'package.json'));
|
|
17
|
+
} catch {
|
|
18
|
+
return localRequire;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function safeResolve(requireFn, specifier) {
|
|
23
|
+
try {
|
|
24
|
+
return requireFn.resolve(specifier);
|
|
25
|
+
} catch {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function resolveBinary(candidates) {
|
|
31
|
+
for (const candidate of candidates) {
|
|
32
|
+
if (existsSync(candidate)) {
|
|
33
|
+
return candidate;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return candidates[0] || '';
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function resolvePackageRoot(packageName, projectRoot = null) {
|
|
40
|
+
const projectRequire = safeCreateRequire(projectRoot);
|
|
41
|
+
const projectPath = safeResolve(projectRequire, `${packageName}/package.json`);
|
|
42
|
+
if (projectPath) {
|
|
43
|
+
return dirname(projectPath);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const localPath = safeResolve(localRequire, `${packageName}/package.json`);
|
|
47
|
+
return localPath ? dirname(localPath) : null;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function readInstalledPackageVersion(packageName, projectRoot = null) {
|
|
51
|
+
const packageRoot = resolvePackageRoot(packageName, projectRoot);
|
|
52
|
+
if (!packageRoot) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
try {
|
|
56
|
+
const pkg = JSON.parse(readFileSync(resolve(packageRoot, 'package.json'), 'utf8'));
|
|
57
|
+
return typeof pkg.version === 'string' ? pkg.version : null;
|
|
58
|
+
} catch {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function readCliPackageVersion() {
|
|
64
|
+
try {
|
|
65
|
+
const pkg = JSON.parse(readFileSync(resolve(CLI_ROOT, 'package.json'), 'utf8'));
|
|
66
|
+
return typeof pkg.version === 'string' ? pkg.version : '0.0.0';
|
|
67
|
+
} catch {
|
|
68
|
+
return '0.0.0';
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function compilerBinCandidates(projectRoot = null) {
|
|
73
|
+
const candidates = [
|
|
74
|
+
resolve(CLI_ROOT, '../compiler/target/release/zenith-compiler'),
|
|
75
|
+
resolve(CLI_ROOT, '../zenith-compiler/target/release/zenith-compiler')
|
|
76
|
+
];
|
|
77
|
+
const installedRoot = resolvePackageRoot('@zenithbuild/compiler', projectRoot);
|
|
78
|
+
if (installedRoot) {
|
|
79
|
+
candidates.unshift(resolve(installedRoot, 'target/release/zenith-compiler'));
|
|
80
|
+
}
|
|
81
|
+
return candidates;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function resolveCompilerBin(projectRoot = null) {
|
|
85
|
+
return resolveBinary(compilerBinCandidates(projectRoot));
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function bundlerBinCandidates(projectRoot = null, env = process.env) {
|
|
89
|
+
const candidates = [];
|
|
90
|
+
const envBin = env?.ZENITH_BUNDLER_BIN;
|
|
91
|
+
if (typeof envBin === 'string' && envBin.length > 0) {
|
|
92
|
+
candidates.push(envBin);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const installedRoot = resolvePackageRoot('@zenithbuild/bundler', projectRoot);
|
|
96
|
+
if (installedRoot) {
|
|
97
|
+
candidates.push(resolve(installedRoot, 'target/release/zenith-bundler'));
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
candidates.push(
|
|
101
|
+
resolve(CLI_ROOT, '../bundler/target/release/zenith-bundler'),
|
|
102
|
+
resolve(CLI_ROOT, '../zenith-bundler/target/release/zenith-bundler')
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
return candidates;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export function resolveBundlerBin(projectRoot = null, env = process.env) {
|
|
109
|
+
return resolveBinary(bundlerBinCandidates(projectRoot, env));
|
|
110
|
+
}
|
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
3
|
+
import { join, resolve } from 'node:path';
|
|
4
|
+
import {
|
|
5
|
+
readCliPackageVersion,
|
|
6
|
+
readInstalledPackageVersion,
|
|
7
|
+
resolveBundlerBin
|
|
8
|
+
} from './toolchain-paths.js';
|
|
9
|
+
|
|
10
|
+
const PACKAGE_KEYS = [
|
|
11
|
+
['core', '@zenithbuild/core'],
|
|
12
|
+
['compiler', '@zenithbuild/compiler'],
|
|
13
|
+
['runtime', '@zenithbuild/runtime'],
|
|
14
|
+
['router', '@zenithbuild/router'],
|
|
15
|
+
['bundlerPackage', '@zenithbuild/bundler']
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
function parseVersion(version) {
|
|
19
|
+
const raw = String(version || '').trim();
|
|
20
|
+
const match = raw.match(/^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?$/);
|
|
21
|
+
if (!match) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
raw,
|
|
26
|
+
major: Number.parseInt(match[1], 10),
|
|
27
|
+
minor: Number.parseInt(match[2], 10),
|
|
28
|
+
patch: Number.parseInt(match[3], 10),
|
|
29
|
+
prerelease: match[4] || '',
|
|
30
|
+
prereleaseParts: match[4] ? match[4].split('.') : []
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function compareIdentifiers(left, right) {
|
|
35
|
+
const leftNumeric = /^\d+$/.test(left);
|
|
36
|
+
const rightNumeric = /^\d+$/.test(right);
|
|
37
|
+
if (leftNumeric && rightNumeric) {
|
|
38
|
+
return Number(left) - Number(right);
|
|
39
|
+
}
|
|
40
|
+
if (leftNumeric) {
|
|
41
|
+
return -1;
|
|
42
|
+
}
|
|
43
|
+
if (rightNumeric) {
|
|
44
|
+
return 1;
|
|
45
|
+
}
|
|
46
|
+
return left.localeCompare(right);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function compareVersions(leftVersion, rightVersion) {
|
|
50
|
+
const left = parseVersion(leftVersion);
|
|
51
|
+
const right = parseVersion(rightVersion);
|
|
52
|
+
if (!left && !right) return 0;
|
|
53
|
+
if (!left) return -1;
|
|
54
|
+
if (!right) return 1;
|
|
55
|
+
|
|
56
|
+
const numberDelta = (
|
|
57
|
+
(left.major - right.major)
|
|
58
|
+
|| (left.minor - right.minor)
|
|
59
|
+
|| (left.patch - right.patch)
|
|
60
|
+
);
|
|
61
|
+
if (numberDelta !== 0) {
|
|
62
|
+
return numberDelta;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (!left.prerelease && !right.prerelease) {
|
|
66
|
+
return 0;
|
|
67
|
+
}
|
|
68
|
+
if (!left.prerelease) {
|
|
69
|
+
return 1;
|
|
70
|
+
}
|
|
71
|
+
if (!right.prerelease) {
|
|
72
|
+
return -1;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const len = Math.max(left.prereleaseParts.length, right.prereleaseParts.length);
|
|
76
|
+
for (let index = 0; index < len; index += 1) {
|
|
77
|
+
const leftPart = left.prereleaseParts[index];
|
|
78
|
+
const rightPart = right.prereleaseParts[index];
|
|
79
|
+
if (leftPart === undefined) {
|
|
80
|
+
return -1;
|
|
81
|
+
}
|
|
82
|
+
if (rightPart === undefined) {
|
|
83
|
+
return 1;
|
|
84
|
+
}
|
|
85
|
+
const delta = compareIdentifiers(leftPart, rightPart);
|
|
86
|
+
if (delta !== 0) {
|
|
87
|
+
return delta;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return 0;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function prereleaseChannel(parsed) {
|
|
95
|
+
if (!parsed || !parsed.prerelease) {
|
|
96
|
+
return 'stable';
|
|
97
|
+
}
|
|
98
|
+
const [label = 'prerelease', train] = parsed.prereleaseParts;
|
|
99
|
+
if (train && /^\d+$/.test(train)) {
|
|
100
|
+
return `${label}.${train}`;
|
|
101
|
+
}
|
|
102
|
+
return label;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function classifyDifference(expectedVersion, actualVersion) {
|
|
106
|
+
if (!expectedVersion || !actualVersion) {
|
|
107
|
+
return 'unknown';
|
|
108
|
+
}
|
|
109
|
+
if (expectedVersion === actualVersion) {
|
|
110
|
+
return 'exact';
|
|
111
|
+
}
|
|
112
|
+
const expected = parseVersion(expectedVersion);
|
|
113
|
+
const actual = parseVersion(actualVersion);
|
|
114
|
+
if (!expected || !actual) {
|
|
115
|
+
return 'unknown';
|
|
116
|
+
}
|
|
117
|
+
if (expected.major !== actual.major || expected.minor !== actual.minor) {
|
|
118
|
+
return 'hard';
|
|
119
|
+
}
|
|
120
|
+
if (prereleaseChannel(expected) !== prereleaseChannel(actual)) {
|
|
121
|
+
return 'hard';
|
|
122
|
+
}
|
|
123
|
+
return 'soft';
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function readProjectPackage(projectRoot) {
|
|
127
|
+
if (!projectRoot) {
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
try {
|
|
131
|
+
const manifestPath = resolve(projectRoot, 'package.json');
|
|
132
|
+
if (!existsSync(manifestPath)) {
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
return JSON.parse(readFileSync(manifestPath, 'utf8'));
|
|
136
|
+
} catch {
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function buildFixCommand(projectRoot, targetVersion) {
|
|
142
|
+
const manifest = readProjectPackage(projectRoot);
|
|
143
|
+
const dependencyNames = [
|
|
144
|
+
'@zenithbuild/core',
|
|
145
|
+
'@zenithbuild/cli',
|
|
146
|
+
'@zenithbuild/compiler',
|
|
147
|
+
'@zenithbuild/runtime',
|
|
148
|
+
'@zenithbuild/router',
|
|
149
|
+
'@zenithbuild/bundler'
|
|
150
|
+
];
|
|
151
|
+
|
|
152
|
+
const deps = [];
|
|
153
|
+
const devDeps = [];
|
|
154
|
+
for (const name of dependencyNames) {
|
|
155
|
+
if (manifest?.dependencies && Object.prototype.hasOwnProperty.call(manifest.dependencies, name)) {
|
|
156
|
+
deps.push(`${name}@${targetVersion}`);
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
devDeps.push(`${name}@${targetVersion}`);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const commands = [];
|
|
163
|
+
if (deps.length > 0) {
|
|
164
|
+
commands.push(`npm i ${deps.join(' ')}`);
|
|
165
|
+
}
|
|
166
|
+
if (devDeps.length > 0) {
|
|
167
|
+
commands.push(`npm i -D ${devDeps.join(' ')}`);
|
|
168
|
+
}
|
|
169
|
+
if (commands.length === 0) {
|
|
170
|
+
commands.push(`npm i -D ${dependencyNames.map((name) => `${name}@${targetVersion}`).join(' ')}`);
|
|
171
|
+
}
|
|
172
|
+
return commands.join(' && ');
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function describeVersions(versions) {
|
|
176
|
+
const entries = [
|
|
177
|
+
['cli', versions.cli],
|
|
178
|
+
['project cli', versions.projectCli],
|
|
179
|
+
['core', versions.core],
|
|
180
|
+
['compiler', versions.compiler],
|
|
181
|
+
['runtime', versions.runtime],
|
|
182
|
+
['router', versions.router],
|
|
183
|
+
['bundler pkg', versions.bundlerPackage],
|
|
184
|
+
['bundler bin', versions.bundlerBinary]
|
|
185
|
+
];
|
|
186
|
+
return entries
|
|
187
|
+
.filter(([, version]) => typeof version === 'string' && version.length > 0)
|
|
188
|
+
.map(([label, version]) => `${label}=${version}`)
|
|
189
|
+
.join(' ');
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function summarizeIssues(issues) {
|
|
193
|
+
const preview = issues.slice(0, 3).map((issue) => issue.summary);
|
|
194
|
+
const suffix = issues.length > 3 ? ` +${issues.length - 3} more` : '';
|
|
195
|
+
return `${preview.join('; ')}${suffix}`;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function determineTargetVersion(versions) {
|
|
199
|
+
const candidates = [
|
|
200
|
+
versions.projectCli,
|
|
201
|
+
versions.core,
|
|
202
|
+
versions.compiler,
|
|
203
|
+
versions.runtime,
|
|
204
|
+
versions.router,
|
|
205
|
+
versions.bundlerPackage,
|
|
206
|
+
versions.cli
|
|
207
|
+
].filter((value) => typeof value === 'string' && value.length > 0);
|
|
208
|
+
|
|
209
|
+
if (candidates.length === 0) {
|
|
210
|
+
return '0.0.0';
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
let highest = candidates[0];
|
|
214
|
+
for (const candidate of candidates.slice(1)) {
|
|
215
|
+
if (compareVersions(candidate, highest) > 0) {
|
|
216
|
+
highest = candidate;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
return highest;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
export function getBundlerVersion(bundlerBinPath) {
|
|
223
|
+
const path = String(bundlerBinPath || '').trim();
|
|
224
|
+
if (!path) {
|
|
225
|
+
return { version: null, path: '', rawOutput: '', ok: false };
|
|
226
|
+
}
|
|
227
|
+
const result = spawnSync(path, ['--version'], { encoding: 'utf8' });
|
|
228
|
+
if (result.error) {
|
|
229
|
+
return {
|
|
230
|
+
version: null,
|
|
231
|
+
path,
|
|
232
|
+
rawOutput: result.error.message,
|
|
233
|
+
ok: false
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
const rawOutput = `${result.stdout || ''}\n${result.stderr || ''}`.trim();
|
|
238
|
+
const versionMatch = rawOutput.match(/(\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?)/);
|
|
239
|
+
return {
|
|
240
|
+
version: versionMatch ? versionMatch[1] : null,
|
|
241
|
+
path,
|
|
242
|
+
rawOutput,
|
|
243
|
+
ok: result.status === 0 && Boolean(versionMatch)
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
export function getLocalZenithVersions({ projectRoot, bundlerBinPath } = {}) {
|
|
248
|
+
const resolvedBundlerBin = bundlerBinPath || resolveBundlerBin(projectRoot);
|
|
249
|
+
const bundlerVersion = getBundlerVersion(resolvedBundlerBin);
|
|
250
|
+
const versions = {
|
|
251
|
+
cli: readCliPackageVersion(),
|
|
252
|
+
projectCli: readInstalledPackageVersion('@zenithbuild/cli', projectRoot),
|
|
253
|
+
bundlerBinary: bundlerVersion.version,
|
|
254
|
+
bundlerBinPath: bundlerVersion.path,
|
|
255
|
+
bundlerBinRawOutput: bundlerVersion.rawOutput,
|
|
256
|
+
targetVersion: null
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
for (const [key, packageName] of PACKAGE_KEYS) {
|
|
260
|
+
versions[key] = readInstalledPackageVersion(packageName, projectRoot);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
versions.targetVersion = determineTargetVersion(versions);
|
|
264
|
+
return versions;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
export function checkCompatibility(versions) {
|
|
268
|
+
const targetVersion = versions?.targetVersion || determineTargetVersion(versions || {});
|
|
269
|
+
const issues = [];
|
|
270
|
+
const fixCommand = buildFixCommand(versions?.projectRoot, targetVersion);
|
|
271
|
+
|
|
272
|
+
const addIssue = (code, summary, message) => {
|
|
273
|
+
issues.push({
|
|
274
|
+
code,
|
|
275
|
+
summary,
|
|
276
|
+
message,
|
|
277
|
+
hint: `${fixCommand} (suppress with ZENITH_SKIP_VERSION_CHECK=1)`,
|
|
278
|
+
fixCommand
|
|
279
|
+
});
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
if (versions.projectCli && versions.cli && versions.projectCli !== versions.cli) {
|
|
283
|
+
const severity = classifyDifference(versions.projectCli, versions.cli);
|
|
284
|
+
addIssue(
|
|
285
|
+
severity === 'hard' ? 'CLI_TRAIN_MISMATCH' : 'CLI_OUTDATED',
|
|
286
|
+
`cli ${versions.cli} != project ${versions.projectCli}`,
|
|
287
|
+
`Version mismatch detected (may break HMR/refs): executing CLI ${versions.cli} does not match project CLI ${versions.projectCli}.`
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
for (const [key, label] of [
|
|
292
|
+
['core', 'core'],
|
|
293
|
+
['compiler', 'compiler'],
|
|
294
|
+
['runtime', 'runtime'],
|
|
295
|
+
['router', 'router'],
|
|
296
|
+
['bundlerPackage', 'bundler package']
|
|
297
|
+
]) {
|
|
298
|
+
const actual = versions[key];
|
|
299
|
+
const difference = classifyDifference(targetVersion, actual);
|
|
300
|
+
if (difference === 'hard') {
|
|
301
|
+
addIssue(
|
|
302
|
+
'VERSION_TRAIN_MISMATCH',
|
|
303
|
+
`${label} ${actual} != ${targetVersion}`,
|
|
304
|
+
`Version mismatch detected (may break HMR/refs): ${label} ${actual} is on a different Zenith train than ${targetVersion}.`
|
|
305
|
+
);
|
|
306
|
+
} else if (difference === 'soft') {
|
|
307
|
+
addIssue(
|
|
308
|
+
'VERSION_OUTDATED',
|
|
309
|
+
`${label} ${actual} != ${targetVersion}`,
|
|
310
|
+
`Version mismatch detected (may break HMR/refs): ${label} ${actual} is not aligned with ${targetVersion}.`
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
const bundlerExpected = versions.bundlerPackage || targetVersion;
|
|
316
|
+
const bundlerDifference = classifyDifference(bundlerExpected, versions.bundlerBinary);
|
|
317
|
+
if (bundlerDifference === 'hard') {
|
|
318
|
+
addIssue(
|
|
319
|
+
'BUNDLER_BINARY_MISMATCH',
|
|
320
|
+
`bundler bin ${versions.bundlerBinary || 'missing'} != ${bundlerExpected}`,
|
|
321
|
+
`Version mismatch detected (may break build/IR contracts): bundler binary ${versions.bundlerBinary || 'missing'} does not match ${bundlerExpected}.`
|
|
322
|
+
);
|
|
323
|
+
} else if (bundlerDifference === 'soft') {
|
|
324
|
+
addIssue(
|
|
325
|
+
'BUNDLER_BINARY_OUTDATED',
|
|
326
|
+
`bundler bin ${versions.bundlerBinary} != ${bundlerExpected}`,
|
|
327
|
+
`Version mismatch detected (may break build/IR contracts): bundler binary ${versions.bundlerBinary} is not aligned with ${bundlerExpected}.`
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
return {
|
|
332
|
+
status: issues.length === 0 ? 'ok' : 'warn',
|
|
333
|
+
issues,
|
|
334
|
+
details: {
|
|
335
|
+
targetVersion,
|
|
336
|
+
versions: {
|
|
337
|
+
...versions
|
|
338
|
+
},
|
|
339
|
+
summary: describeVersions(versions)
|
|
340
|
+
}
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
export async function maybeWarnAboutZenithVersionMismatch({
|
|
345
|
+
projectRoot,
|
|
346
|
+
logger,
|
|
347
|
+
command = 'build',
|
|
348
|
+
bundlerBinPath = null
|
|
349
|
+
} = {}) {
|
|
350
|
+
if (!logger || process.env.ZENITH_SKIP_VERSION_CHECK === '1') {
|
|
351
|
+
return { status: 'ok', issues: [], details: {} };
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
const versions = getLocalZenithVersions({ projectRoot, bundlerBinPath });
|
|
355
|
+
versions.projectRoot = projectRoot;
|
|
356
|
+
const result = checkCompatibility(versions);
|
|
357
|
+
const onceKey = `zenith-version-check:${describeVersions(versions)}:${result.status}`;
|
|
358
|
+
const verboseTag = command === 'dev' ? 'DEV' : 'BUILD';
|
|
359
|
+
|
|
360
|
+
if (result.status === 'ok') {
|
|
361
|
+
logger.verbose(verboseTag, `toolchain versions ok ${result.details.summary}`);
|
|
362
|
+
return result;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
const primary = result.issues[0];
|
|
366
|
+
logger.warn(
|
|
367
|
+
`${primary.message} ${summarizeIssues(result.issues)}`,
|
|
368
|
+
{
|
|
369
|
+
onceKey,
|
|
370
|
+
hint: primary.hint
|
|
371
|
+
}
|
|
372
|
+
);
|
|
373
|
+
logger.verbose(verboseTag, `toolchain versions ${result.details.summary}`);
|
|
374
|
+
if (versions.bundlerBinPath) {
|
|
375
|
+
logger.verbose(verboseTag, `bundler bin path=${versions.bundlerBinPath}`);
|
|
376
|
+
}
|
|
377
|
+
return result;
|
|
378
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zenithbuild/cli",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.4",
|
|
4
4
|
"description": "Deterministic project orchestrator for Zenith framework",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"prepublishOnly": "npm run build"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@zenithbuild/compiler": "0.6.
|
|
27
|
+
"@zenithbuild/compiler": "0.6.4",
|
|
28
28
|
"picocolors": "^1.1.1"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|