wyvrnpm 2.0.2 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +382 -4
- package/bin/wyvrn.js +96 -3
- package/cmake/cpp.cmake +9 -0
- package/cmake/functions.cmake +224 -0
- package/cmake/macros.cmake +233 -0
- package/cmake/options.cmake +23 -0
- package/cmake/variables.cmake +171 -0
- package/package.json +2 -1
- package/src/build/cache.js +101 -0
- package/src/build/clone.js +170 -0
- package/src/build/cmake.js +342 -0
- package/src/build/index.js +244 -0
- package/src/build/msvc-env.js +217 -0
- package/src/build/recipe.js +129 -0
- package/src/commands/build.js +242 -0
- package/src/commands/clean.js +25 -9
- package/src/commands/configure.js +6 -5
- package/src/commands/init.js +3 -2
- package/src/commands/install.js +61 -14
- package/src/commands/link.js +18 -15
- package/src/commands/profile.js +15 -12
- package/src/commands/publish.js +67 -31
- package/src/compat.js +232 -0
- package/src/config.js +3 -1
- package/src/download.js +369 -87
- package/src/logger.js +78 -0
- package/src/profile.js +28 -0
- package/src/providers/file.js +4 -3
- package/src/providers/http.js +3 -2
- package/src/providers/s3.js +3 -2
- package/src/resolve.js +33 -7
- package/src/toolchain/deps.js +164 -0
- package/src/toolchain/index.js +141 -0
- package/src/toolchain/presets.js +191 -0
- package/src/toolchain/template.cmake +66 -0
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const { spawn } = require('child_process');
|
|
6
|
+
|
|
7
|
+
const { readConfig } = require('../config');
|
|
8
|
+
const install = require('./install');
|
|
9
|
+
const log = require('../logger');
|
|
10
|
+
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
// Pure helpers (unit-testable — no process spawning, no filesystem writes)
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Decide whether `wyvrn install` must run before build.
|
|
17
|
+
*
|
|
18
|
+
* - toolchain-missing : wyvrn_toolchain.cmake does not exist → definitely stale.
|
|
19
|
+
* - lock-newer : wyvrn.lock was modified after the toolchain was written,
|
|
20
|
+
* so the toolchain's package list is out of date.
|
|
21
|
+
* - fresh : no action needed.
|
|
22
|
+
*
|
|
23
|
+
* @param {{ rootDir: string, manifestPath: string }} args
|
|
24
|
+
* @returns {{ stale: boolean, reason: string }}
|
|
25
|
+
*/
|
|
26
|
+
function isToolchainStale({ rootDir, manifestPath }) {
|
|
27
|
+
const lockPath = path.join(path.dirname(manifestPath), 'wyvrn.lock');
|
|
28
|
+
const toolchainPath = path.join(rootDir, 'wyvrn_internal', 'wyvrn_toolchain.cmake');
|
|
29
|
+
|
|
30
|
+
if (!fs.existsSync(toolchainPath)) {
|
|
31
|
+
return { stale: true, reason: 'toolchain-missing' };
|
|
32
|
+
}
|
|
33
|
+
if (!fs.existsSync(lockPath)) {
|
|
34
|
+
return { stale: false, reason: 'no-lock' };
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const lockMtime = fs.statSync(lockPath).mtimeMs;
|
|
38
|
+
const toolchainMtime = fs.statSync(toolchainPath).mtimeMs;
|
|
39
|
+
if (lockMtime > toolchainMtime) {
|
|
40
|
+
return { stale: true, reason: 'lock-newer-than-toolchain' };
|
|
41
|
+
}
|
|
42
|
+
return { stale: false, reason: 'fresh' };
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Resolve the configure preset name from CLI override or profile convention.
|
|
47
|
+
*
|
|
48
|
+
* @param {{ presetOverride?: string, profileName: string }} args
|
|
49
|
+
* @returns {string}
|
|
50
|
+
*/
|
|
51
|
+
function resolvePresetName({ presetOverride, profileName }) {
|
|
52
|
+
if (presetOverride) return presetOverride;
|
|
53
|
+
return `wyvrn-${profileName}`;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Compute the build directory for a preset, matching the pattern emitted
|
|
58
|
+
* by [src/toolchain/presets.js](../toolchain/presets.js) — `${sourceDir}/build/<preset>`.
|
|
59
|
+
*
|
|
60
|
+
* @param {{ rootDir: string, presetName: string }} args
|
|
61
|
+
* @returns {string}
|
|
62
|
+
*/
|
|
63
|
+
function resolveBinaryDir({ rootDir, presetName }) {
|
|
64
|
+
return path.join(rootDir, 'build', presetName);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Args passed to `cmake` for the configure step.
|
|
69
|
+
* @param {{ presetName: string }} args
|
|
70
|
+
* @returns {string[]}
|
|
71
|
+
*/
|
|
72
|
+
function buildConfigureArgs({ presetName }) {
|
|
73
|
+
return ['--preset', presetName];
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Args passed to `cmake` for the build step.
|
|
78
|
+
*
|
|
79
|
+
* @param {{
|
|
80
|
+
* binaryDir: string,
|
|
81
|
+
* config: string,
|
|
82
|
+
* target?: string,
|
|
83
|
+
* verbose?: boolean,
|
|
84
|
+
* passthru?: string[],
|
|
85
|
+
* }} args
|
|
86
|
+
* @returns {string[]}
|
|
87
|
+
*/
|
|
88
|
+
function buildBuildArgs({ binaryDir, config, target, verbose, passthru = [] }) {
|
|
89
|
+
const args = ['--build', binaryDir, '--config', config];
|
|
90
|
+
if (verbose) args.push('--verbose');
|
|
91
|
+
if (target) args.push('--target', target);
|
|
92
|
+
if (passthru.length > 0) args.push('--', ...passthru);
|
|
93
|
+
return args;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Args passed to `cmake --install` for the install step.
|
|
98
|
+
*
|
|
99
|
+
* @param {{
|
|
100
|
+
* binaryDir: string,
|
|
101
|
+
* config: string,
|
|
102
|
+
* prefix?: string, // override CMAKE_INSTALL_PREFIX at install time
|
|
103
|
+
* }} args
|
|
104
|
+
* @returns {string[]}
|
|
105
|
+
*/
|
|
106
|
+
function buildInstallArgs({ binaryDir, config, prefix }) {
|
|
107
|
+
const args = ['--install', binaryDir, '--config', config];
|
|
108
|
+
if (prefix) args.push('--prefix', prefix);
|
|
109
|
+
return args;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// ---------------------------------------------------------------------------
|
|
113
|
+
// Spawn wrapper
|
|
114
|
+
// ---------------------------------------------------------------------------
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Run `cmake` with the given args. Inherits stdio for real-time output.
|
|
118
|
+
* Rejects if the process exits non-zero or fails to spawn.
|
|
119
|
+
*
|
|
120
|
+
* @param {string[]} args
|
|
121
|
+
* @returns {Promise<void>}
|
|
122
|
+
*/
|
|
123
|
+
function runCmake(args) {
|
|
124
|
+
return new Promise((resolve, reject) => {
|
|
125
|
+
const proc = spawn('cmake', args, { stdio: 'inherit' });
|
|
126
|
+
proc.on('error', (err) => {
|
|
127
|
+
reject(new Error(
|
|
128
|
+
`Failed to spawn cmake: ${err.message}\n` +
|
|
129
|
+
' Is CMake installed and on PATH?',
|
|
130
|
+
));
|
|
131
|
+
});
|
|
132
|
+
proc.on('close', (code) => {
|
|
133
|
+
if (code === 0) resolve();
|
|
134
|
+
else reject(new Error(`cmake ${args.join(' ')} exited with code ${code}`));
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// ---------------------------------------------------------------------------
|
|
140
|
+
// Command entry
|
|
141
|
+
// ---------------------------------------------------------------------------
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* `wyvrnpm build` — configure + build via the generated CMake preset.
|
|
145
|
+
*
|
|
146
|
+
* Defaults:
|
|
147
|
+
* - preset : `wyvrn-<profileName>` (from --profile or config.defaultProfile)
|
|
148
|
+
* - config : Release
|
|
149
|
+
* - auto-install when toolchain is missing / older than wyvrn.lock
|
|
150
|
+
*
|
|
151
|
+
* @param {object} argv
|
|
152
|
+
*/
|
|
153
|
+
async function build(argv) {
|
|
154
|
+
const rootDir = path.resolve(argv.root);
|
|
155
|
+
const manifestPath = path.resolve(argv.manifest);
|
|
156
|
+
|
|
157
|
+
const config = readConfig();
|
|
158
|
+
const profileName = argv.profile ?? config.defaultProfile ?? 'default';
|
|
159
|
+
const presetName = resolvePresetName({ presetOverride: argv.preset, profileName });
|
|
160
|
+
const buildConfig = argv.config ?? 'Release';
|
|
161
|
+
|
|
162
|
+
// ── Stale check / auto-install ────────────────────────────────────────────
|
|
163
|
+
// `--auto-install` gates the "run `wyvrnpm install` first when the
|
|
164
|
+
// toolchain is missing or older than wyvrn.lock" behaviour. The separate
|
|
165
|
+
// `--install` flag below runs `cmake --install` AFTER build; the two are
|
|
166
|
+
// deliberately distinct concepts.
|
|
167
|
+
const staleness = isToolchainStale({ rootDir, manifestPath });
|
|
168
|
+
if (staleness.stale) {
|
|
169
|
+
if (argv.autoInstall === false) {
|
|
170
|
+
log.error(
|
|
171
|
+
`toolchain is stale (${staleness.reason}) and --no-auto-install was passed.\n` +
|
|
172
|
+
' Run: wyvrnpm install',
|
|
173
|
+
);
|
|
174
|
+
process.exit(1);
|
|
175
|
+
}
|
|
176
|
+
log.info(`Toolchain ${staleness.reason} — running install first`);
|
|
177
|
+
await install({
|
|
178
|
+
manifest: argv.manifest,
|
|
179
|
+
root: argv.root,
|
|
180
|
+
profile: argv.profile,
|
|
181
|
+
source: argv.source,
|
|
182
|
+
platform: argv.platform ?? 'win_x64',
|
|
183
|
+
timeout: argv.timeout ?? 300,
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const binaryDir = resolveBinaryDir({ rootDir, presetName });
|
|
188
|
+
|
|
189
|
+
// ── Clean ─────────────────────────────────────────────────────────────────
|
|
190
|
+
if (argv.clean && fs.existsSync(binaryDir)) {
|
|
191
|
+
log.info(`Removing ${binaryDir}`);
|
|
192
|
+
fs.rmSync(binaryDir, { recursive: true, force: true });
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// ── Configure ─────────────────────────────────────────────────────────────
|
|
196
|
+
const configureArgs = buildConfigureArgs({ presetName });
|
|
197
|
+
log.info(`cmake ${configureArgs.join(' ')}`);
|
|
198
|
+
await runCmake(configureArgs);
|
|
199
|
+
|
|
200
|
+
// ── Build ─────────────────────────────────────────────────────────────────
|
|
201
|
+
const buildArgs = buildBuildArgs({
|
|
202
|
+
binaryDir,
|
|
203
|
+
config: buildConfig,
|
|
204
|
+
target: argv.target,
|
|
205
|
+
verbose: argv.verbose,
|
|
206
|
+
passthru: argv['--'] ?? [],
|
|
207
|
+
});
|
|
208
|
+
log.info(`cmake ${buildArgs.join(' ')}`);
|
|
209
|
+
await runCmake(buildArgs);
|
|
210
|
+
|
|
211
|
+
// ── Install (optional) ────────────────────────────────────────────────────
|
|
212
|
+
// `--install` runs `cmake --install <binaryDir>` after the build. Prefix
|
|
213
|
+
// defaults to whatever was baked into the cache at configure time; pass
|
|
214
|
+
// `--install-prefix` to override without reconfiguring.
|
|
215
|
+
if (argv.install) {
|
|
216
|
+
const installArgs = buildInstallArgs({
|
|
217
|
+
binaryDir,
|
|
218
|
+
config: buildConfig,
|
|
219
|
+
prefix: argv.installPrefix,
|
|
220
|
+
});
|
|
221
|
+
log.info(`cmake ${installArgs.join(' ')}`);
|
|
222
|
+
await runCmake(installArgs);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const suffix = argv.install
|
|
226
|
+
? ` + installed${argv.installPrefix ? ` to ${argv.installPrefix}` : ''}`
|
|
227
|
+
: '';
|
|
228
|
+
log.success(`Build complete: ${binaryDir} (${buildConfig})${suffix}`);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
module.exports = build;
|
|
232
|
+
module.exports.default = build;
|
|
233
|
+
|
|
234
|
+
// Exported for unit tests
|
|
235
|
+
module.exports._helpers = {
|
|
236
|
+
isToolchainStale,
|
|
237
|
+
resolvePresetName,
|
|
238
|
+
resolveBinaryDir,
|
|
239
|
+
buildConfigureArgs,
|
|
240
|
+
buildBuildArgs,
|
|
241
|
+
buildInstallArgs,
|
|
242
|
+
};
|
package/src/commands/clean.js
CHANGED
|
@@ -3,16 +3,22 @@
|
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
const path = require('path');
|
|
5
5
|
|
|
6
|
+
const { clearBuildCache, getBuildCacheRoot } = require('../build/cache');
|
|
7
|
+
const log = require('../logger');
|
|
8
|
+
|
|
6
9
|
/**
|
|
7
|
-
* Removes the wyvrn_internal
|
|
10
|
+
* Removes the project's `wyvrn_internal/` package cache and `wyvrn.lock` file.
|
|
11
|
+
* With `--build-cache`, also clears the machine-wide source-build cache
|
|
12
|
+
* under `%LOCALAPPDATA%\wyvrnpm\bc\` (shared across projects).
|
|
8
13
|
*
|
|
9
|
-
* @param {object}
|
|
10
|
-
* @param {string}
|
|
11
|
-
* @param {string}
|
|
14
|
+
* @param {object} argv
|
|
15
|
+
* @param {string} argv.root Project root directory.
|
|
16
|
+
* @param {string} argv.manifest Path to the manifest file (used to locate wyvrn.lock).
|
|
17
|
+
* @param {boolean} [argv.buildCache] When true, also nukes the source-build cache.
|
|
12
18
|
* @returns {Promise<void>}
|
|
13
19
|
*/
|
|
14
20
|
async function clean(argv) {
|
|
15
|
-
const rootDir
|
|
21
|
+
const rootDir = path.resolve(argv.root);
|
|
16
22
|
const razerDir = path.join(rootDir, 'wyvrn_internal');
|
|
17
23
|
const lockPath = path.join(path.dirname(path.resolve(argv.manifest)), 'wyvrn.lock');
|
|
18
24
|
|
|
@@ -20,20 +26,30 @@ async function clean(argv) {
|
|
|
20
26
|
|
|
21
27
|
if (fs.existsSync(razerDir)) {
|
|
22
28
|
fs.rmSync(razerDir, { recursive: true, force: true });
|
|
23
|
-
|
|
29
|
+
log.info(`Removed ${razerDir}`);
|
|
24
30
|
removedAnything = true;
|
|
25
31
|
} else {
|
|
26
|
-
|
|
32
|
+
log.info(`Nothing to clean at ${razerDir}`);
|
|
27
33
|
}
|
|
28
34
|
|
|
29
35
|
if (fs.existsSync(lockPath)) {
|
|
30
36
|
fs.unlinkSync(lockPath);
|
|
31
|
-
|
|
37
|
+
log.info(`Removed ${lockPath}`);
|
|
32
38
|
removedAnything = true;
|
|
33
39
|
}
|
|
34
40
|
|
|
41
|
+
if (argv.buildCache) {
|
|
42
|
+
const removed = clearBuildCache();
|
|
43
|
+
if (removed) {
|
|
44
|
+
log.info(`Removed source-build cache ${removed}`);
|
|
45
|
+
removedAnything = true;
|
|
46
|
+
} else {
|
|
47
|
+
log.info(`No source-build cache at ${getBuildCacheRoot()}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
35
51
|
if (!removedAnything) {
|
|
36
|
-
|
|
52
|
+
log.info('Nothing to clean.');
|
|
37
53
|
}
|
|
38
54
|
}
|
|
39
55
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const { readConfig, writeConfig, getConfigPath } = require('../config');
|
|
4
|
+
const log = require('../logger');
|
|
4
5
|
|
|
5
6
|
/** wyvrnpm configure list */
|
|
6
7
|
function list() {
|
|
@@ -47,14 +48,14 @@ function addSource(argv) {
|
|
|
47
48
|
const idx = config[key].findIndex((s) => s.name === name);
|
|
48
49
|
if (idx !== -1) {
|
|
49
50
|
config[key][idx] = entry;
|
|
50
|
-
|
|
51
|
+
log.info(`Updated ${kind} source "${name}"`);
|
|
51
52
|
} else {
|
|
52
53
|
config[key].push(entry);
|
|
53
|
-
|
|
54
|
+
log.info(`Added ${kind} source "${name}"`);
|
|
54
55
|
}
|
|
55
56
|
|
|
56
57
|
writeConfig(config);
|
|
57
|
-
|
|
58
|
+
log.info(`Saved to ${getConfigPath()}`);
|
|
58
59
|
}
|
|
59
60
|
|
|
60
61
|
/**
|
|
@@ -69,12 +70,12 @@ function removeSource(argv) {
|
|
|
69
70
|
config[key] = config[key].filter((s) => s.name !== name);
|
|
70
71
|
|
|
71
72
|
if (config[key].length === before) {
|
|
72
|
-
|
|
73
|
+
log.error(`No ${kind} source named "${name}"`);
|
|
73
74
|
process.exit(1);
|
|
74
75
|
}
|
|
75
76
|
|
|
76
77
|
writeConfig(config);
|
|
77
|
-
|
|
78
|
+
log.info(`Removed ${kind} source "${name}"`);
|
|
78
79
|
}
|
|
79
80
|
|
|
80
81
|
module.exports = { list, addSource, removeSource };
|
package/src/commands/init.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const { defaultManifest, writeManifest } = require('../manifest');
|
|
6
|
+
const log = require('../logger');
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Initialises a new wyvrn.json manifest in the project root.
|
|
@@ -18,7 +19,7 @@ async function init(argv) {
|
|
|
18
19
|
const rootDir = path.resolve(argv.root);
|
|
19
20
|
|
|
20
21
|
if (fs.existsSync(manifestPath)) {
|
|
21
|
-
|
|
22
|
+
log.info(`Manifest already exists at ${manifestPath}`);
|
|
22
23
|
return;
|
|
23
24
|
}
|
|
24
25
|
|
|
@@ -27,7 +28,7 @@ async function init(argv) {
|
|
|
27
28
|
|
|
28
29
|
writeManifest(manifestPath, manifest);
|
|
29
30
|
|
|
30
|
-
|
|
31
|
+
log.success(`Created manifest at ${manifestPath}`);
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
module.exports = init;
|
package/src/commands/install.js
CHANGED
|
@@ -8,6 +8,8 @@ const { resolveDependencies } = require('../resolv
|
|
|
8
8
|
const { downloadDependencies } = require('../download');
|
|
9
9
|
const { readConfig } = require('../config');
|
|
10
10
|
const { loadProfile, hashProfile, formatProfile, mergeProfile } = require('../profile');
|
|
11
|
+
const { generateToolchain, generateCMakePresets } = require('../toolchain');
|
|
12
|
+
const log = require('../logger');
|
|
11
13
|
|
|
12
14
|
/**
|
|
13
15
|
* Resolves and downloads all dependencies declared in the manifest, then writes
|
|
@@ -23,6 +25,15 @@ const { loadProfile, hashProfile, formatProfile, mergeProfile } = require('../pr
|
|
|
23
25
|
async function install(argv) {
|
|
24
26
|
const manifestPath = path.resolve(argv.manifest);
|
|
25
27
|
const rootDir = path.resolve(argv.root);
|
|
28
|
+
const buildMode = argv.build ?? 'never';
|
|
29
|
+
|
|
30
|
+
if (buildMode === 'always') {
|
|
31
|
+
log.error(
|
|
32
|
+
'--build=always is not implemented (requires PLAN-BUILD-MISSING phase 3).\n' +
|
|
33
|
+
' Use --build=never (default) or --build=missing.',
|
|
34
|
+
);
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
26
37
|
|
|
27
38
|
// ── Auth / sources ────────────────────────────────────────────────────────
|
|
28
39
|
let packageSources;
|
|
@@ -32,13 +43,13 @@ async function install(argv) {
|
|
|
32
43
|
const config = readConfig();
|
|
33
44
|
packageSources = config.installSources.map((s) => s.url);
|
|
34
45
|
if (packageSources.length > 0) {
|
|
35
|
-
|
|
46
|
+
log.info(`Using ${packageSources.length} source(s) from config`);
|
|
36
47
|
}
|
|
37
48
|
}
|
|
38
49
|
|
|
39
50
|
if (packageSources.length === 0) {
|
|
40
|
-
|
|
41
|
-
'
|
|
51
|
+
log.warn(
|
|
52
|
+
'no sources configured. ' +
|
|
42
53
|
'Pass --source <url> or run: wyvrnpm configure add-source --kind install ...',
|
|
43
54
|
);
|
|
44
55
|
}
|
|
@@ -48,7 +59,7 @@ async function install(argv) {
|
|
|
48
59
|
const profileName = argv.profile ?? config.defaultProfile ?? 'default';
|
|
49
60
|
const { profile: baseProfile, fromFile } = loadProfile(profileName);
|
|
50
61
|
|
|
51
|
-
|
|
62
|
+
log.info(`Profile: "${profileName}"${fromFile ? '' : ' (auto-detected)'}`);
|
|
52
63
|
console.log(formatProfile(baseProfile).split('\n').map((l) => ` ${l}`).join('\n'));
|
|
53
64
|
console.log(` Profile hash : ${hashProfile(baseProfile)}`);
|
|
54
65
|
|
|
@@ -63,9 +74,9 @@ async function install(argv) {
|
|
|
63
74
|
const ver = typeof entry === 'string' ? entry : entry.version;
|
|
64
75
|
if (ver) lockedVersions.set(name, ver);
|
|
65
76
|
}
|
|
66
|
-
|
|
77
|
+
log.info(`Lock file found — ${lockedVersions.size} pinned package(s)`);
|
|
67
78
|
} catch {
|
|
68
|
-
|
|
79
|
+
log.warn('could not read wyvrn.lock, resolving from scratch');
|
|
69
80
|
}
|
|
70
81
|
}
|
|
71
82
|
|
|
@@ -80,8 +91,8 @@ async function install(argv) {
|
|
|
80
91
|
Object.entries(normalizedDeps).map(([name, d]) => [name, d.version]),
|
|
81
92
|
);
|
|
82
93
|
|
|
83
|
-
|
|
84
|
-
`
|
|
94
|
+
log.info(
|
|
95
|
+
`Installing dependencies for "${manifest.name}" (platform: ${argv.platform})`,
|
|
85
96
|
);
|
|
86
97
|
|
|
87
98
|
const resolvedDeps = await resolveDependencies(
|
|
@@ -102,8 +113,8 @@ async function install(argv) {
|
|
|
102
113
|
const profileHash = hashProfile(effectiveProfile);
|
|
103
114
|
|
|
104
115
|
if (Object.keys(depOverrides).length > 0) {
|
|
105
|
-
|
|
106
|
-
|
|
116
|
+
log.info(
|
|
117
|
+
`${name}: settings override → profileHash ${profileHash}` +
|
|
107
118
|
` (${JSON.stringify(depOverrides)})`,
|
|
108
119
|
);
|
|
109
120
|
}
|
|
@@ -115,9 +126,11 @@ async function install(argv) {
|
|
|
115
126
|
|
|
116
127
|
// Extract auth from the first install source (if any)
|
|
117
128
|
const firstInstallSrc = config.installSources?.[0];
|
|
118
|
-
const
|
|
129
|
+
const downloadOptions = {
|
|
119
130
|
awsProfile: firstInstallSrc?.profile ?? undefined,
|
|
120
131
|
token: firstInstallSrc?.token ?? undefined,
|
|
132
|
+
buildMode,
|
|
133
|
+
profileName,
|
|
121
134
|
};
|
|
122
135
|
|
|
123
136
|
const lockEntries = await downloadDependencies(
|
|
@@ -127,7 +140,7 @@ async function install(argv) {
|
|
|
127
140
|
razerDir,
|
|
128
141
|
fetch,
|
|
129
142
|
argv.timeout,
|
|
130
|
-
|
|
143
|
+
downloadOptions,
|
|
131
144
|
);
|
|
132
145
|
|
|
133
146
|
// ── Write v2 lock file ────────────────────────────────────────────────────
|
|
@@ -147,10 +160,44 @@ async function install(argv) {
|
|
|
147
160
|
};
|
|
148
161
|
|
|
149
162
|
fs.writeFileSync(lockPath, JSON.stringify(lockData, null, 2) + '\n', 'utf8');
|
|
150
|
-
|
|
163
|
+
log.info(`Lock file written to ${lockPath}`);
|
|
164
|
+
|
|
165
|
+
// ── CMake toolchain generation ────────────────────────────────────────────
|
|
166
|
+
const packageNames = [...resolvedDeps.keys()].sort();
|
|
167
|
+
const { toolchain } = generateToolchain({
|
|
168
|
+
destDir: razerDir,
|
|
169
|
+
profile: baseProfile,
|
|
170
|
+
profileName,
|
|
171
|
+
profileHash: hashProfile(baseProfile),
|
|
172
|
+
packageNames,
|
|
173
|
+
});
|
|
174
|
+
log.info(`CMake toolchain written to ${toolchain}`);
|
|
175
|
+
|
|
176
|
+
// ── CMakePresets.json emission ────────────────────────────────────────────
|
|
177
|
+
const toolchainRelPath = path
|
|
178
|
+
.relative(rootDir, toolchain)
|
|
179
|
+
.replace(/\\/g, '/');
|
|
180
|
+
const presetResult = generateCMakePresets({
|
|
181
|
+
projectRoot: rootDir,
|
|
182
|
+
profileName,
|
|
183
|
+
profileHash: hashProfile(baseProfile),
|
|
184
|
+
toolchainRelPath,
|
|
185
|
+
});
|
|
186
|
+
if (presetResult.action === 'skipped') {
|
|
187
|
+
log.warn(
|
|
188
|
+
'could not write presets — both CMakePresets.json and ' +
|
|
189
|
+
'CMakeUserPresets.json exist and are user-owned. Add this to your presets:\n' +
|
|
190
|
+
` { "name": "wyvrn-${profileName}", "cacheVariables": { "CMAKE_TOOLCHAIN_FILE": "\${sourceDir}/${toolchainRelPath}" } }`,
|
|
191
|
+
);
|
|
192
|
+
} else {
|
|
193
|
+
log.info(
|
|
194
|
+
`CMake presets ${presetResult.action}: ${presetResult.path}` +
|
|
195
|
+
(presetResult.isUser ? ' (user presets — CMakePresets.json is user-owned)' : ''),
|
|
196
|
+
);
|
|
197
|
+
}
|
|
151
198
|
|
|
152
199
|
const count = resolvedDeps.size;
|
|
153
|
-
|
|
200
|
+
log.success(`Done — ${count} package${count !== 1 ? 's' : ''} installed.`);
|
|
154
201
|
}
|
|
155
202
|
|
|
156
203
|
module.exports = install;
|
package/src/commands/link.js
CHANGED
|
@@ -7,6 +7,7 @@ const { readManifest } = require('../manifest');
|
|
|
7
7
|
const { createLink, isLink, removeLink, getLinkTarget } = require('../link-utils');
|
|
8
8
|
const { downloadDependencies } = require('../download');
|
|
9
9
|
const { resolveDependencies } = require('../resolve');
|
|
10
|
+
const log = require('../logger');
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Normalizes a linked package entry to object form.
|
|
@@ -47,7 +48,7 @@ function registerGlobal(manifestPath, subdir) {
|
|
|
47
48
|
const packageName = manifest.name || manifest.Name;
|
|
48
49
|
|
|
49
50
|
if (!packageName) {
|
|
50
|
-
|
|
51
|
+
log.error('wyvrn.json must have a "name" field');
|
|
51
52
|
process.exit(1);
|
|
52
53
|
}
|
|
53
54
|
|
|
@@ -63,7 +64,7 @@ function registerGlobal(manifestPath, subdir) {
|
|
|
63
64
|
writeConfig(config);
|
|
64
65
|
|
|
65
66
|
const effectivePath = getEffectivePath(entry);
|
|
66
|
-
|
|
67
|
+
log.info(`Registered "${packageName}" → ${effectivePath}`);
|
|
67
68
|
}
|
|
68
69
|
|
|
69
70
|
/**
|
|
@@ -77,7 +78,7 @@ function linkToProject(name, sourcePath, rootDir) {
|
|
|
77
78
|
const absoluteSource = path.resolve(sourcePath);
|
|
78
79
|
|
|
79
80
|
if (!fs.existsSync(absoluteSource)) {
|
|
80
|
-
|
|
81
|
+
log.error(`source path does not exist: ${absoluteSource}`);
|
|
81
82
|
process.exit(1);
|
|
82
83
|
}
|
|
83
84
|
|
|
@@ -106,7 +107,7 @@ function linkToProject(name, sourcePath, rootDir) {
|
|
|
106
107
|
lockData.generatedAt = new Date().toISOString();
|
|
107
108
|
fs.writeFileSync(lockPath, JSON.stringify(lockData, null, 2) + '\n', 'utf8');
|
|
108
109
|
|
|
109
|
-
|
|
110
|
+
log.info(`Linked: ${name} → ${absoluteSource}`);
|
|
110
111
|
}
|
|
111
112
|
|
|
112
113
|
/**
|
|
@@ -122,18 +123,18 @@ async function unlinkFromProject(name, rootDir, restore, argv) {
|
|
|
122
123
|
const linkPath = path.join(razerDir, name);
|
|
123
124
|
|
|
124
125
|
if (!fs.existsSync(linkPath)) {
|
|
125
|
-
|
|
126
|
+
log.error(`package "${name}" is not installed`);
|
|
126
127
|
process.exit(1);
|
|
127
128
|
}
|
|
128
129
|
|
|
129
130
|
if (!isLink(linkPath)) {
|
|
130
|
-
|
|
131
|
+
log.error(`package "${name}" is not a linked package`);
|
|
131
132
|
process.exit(1);
|
|
132
133
|
}
|
|
133
134
|
|
|
134
135
|
// Remove the symlink
|
|
135
136
|
removeLink(linkPath);
|
|
136
|
-
|
|
137
|
+
log.info(`Unlinked: ${name}`);
|
|
137
138
|
|
|
138
139
|
// Update the lock file
|
|
139
140
|
const lockPath = path.join(rootDir, 'wyvrn.lock');
|
|
@@ -161,7 +162,7 @@ async function unlinkFromProject(name, rootDir, restore, argv) {
|
|
|
161
162
|
: rawDeps;
|
|
162
163
|
|
|
163
164
|
if (!deps[name]) {
|
|
164
|
-
|
|
165
|
+
log.warn(`"${name}" is not in manifest dependencies, cannot restore`);
|
|
165
166
|
return;
|
|
166
167
|
}
|
|
167
168
|
|
|
@@ -175,7 +176,7 @@ async function unlinkFromProject(name, rootDir, restore, argv) {
|
|
|
175
176
|
}
|
|
176
177
|
|
|
177
178
|
if (packageSources.length === 0) {
|
|
178
|
-
|
|
179
|
+
log.warn('no sources configured, cannot restore package');
|
|
179
180
|
return;
|
|
180
181
|
}
|
|
181
182
|
|
|
@@ -223,11 +224,11 @@ function listLinked() {
|
|
|
223
224
|
const entries = Object.entries(linked);
|
|
224
225
|
|
|
225
226
|
if (entries.length === 0) {
|
|
226
|
-
|
|
227
|
+
log.info('No globally registered packages');
|
|
227
228
|
return;
|
|
228
229
|
}
|
|
229
230
|
|
|
230
|
-
|
|
231
|
+
log.info('Globally registered packages:');
|
|
231
232
|
for (const [name, rawEntry] of entries) {
|
|
232
233
|
const entry = normalizeLinkedEntry(rawEntry);
|
|
233
234
|
const effectivePath = getEffectivePath(entry);
|
|
@@ -256,7 +257,7 @@ async function link(argv) {
|
|
|
256
257
|
// wyvrnpm link (no args) - register current package globally
|
|
257
258
|
if (!argv.name) {
|
|
258
259
|
if (!fs.existsSync(manifestPath)) {
|
|
259
|
-
|
|
260
|
+
log.error(`no wyvrn.json found at ${manifestPath}`);
|
|
260
261
|
process.exit(1);
|
|
261
262
|
}
|
|
262
263
|
registerGlobal(manifestPath, argv.subdir);
|
|
@@ -278,9 +279,11 @@ async function link(argv) {
|
|
|
278
279
|
const linked = config.linkedPackages || {};
|
|
279
280
|
|
|
280
281
|
if (!linked[argv.name]) {
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
282
|
+
log.error(
|
|
283
|
+
`"${argv.name}" is not registered globally\n` +
|
|
284
|
+
`Run "wyvrnpm link" in the package directory first, or use:\n` +
|
|
285
|
+
` wyvrnpm link ${argv.name} <path>`,
|
|
286
|
+
);
|
|
284
287
|
process.exit(1);
|
|
285
288
|
}
|
|
286
289
|
|