wyvrnpm 2.10.2 → 2.12.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/README.md +1914 -1860
- package/bin/{wyvrn.js → wyvrnpm.js} +66 -0
- package/cmake/cpp.cmake +9 -9
- package/cmake/functions.cmake +224 -224
- package/cmake/macros.cmake +284 -284
- package/package.json +3 -2
- package/src/auth.js +66 -66
- package/src/binary-dir.js +95 -0
- package/src/bootstrap/cookbook.js +196 -196
- package/src/bootstrap/detect.js +150 -150
- package/src/bootstrap/index.js +220 -220
- package/src/bootstrap/version.js +72 -72
- package/src/build/cache.js +344 -344
- package/src/build/clone.js +170 -170
- package/src/build/cmake.js +342 -342
- package/src/build/index.js +299 -297
- package/src/build/msvc-env.js +260 -260
- package/src/build/recipe.js +188 -188
- package/src/commands/add.js +141 -141
- package/src/commands/bootstrap.js +96 -96
- package/src/commands/build.js +482 -452
- package/src/commands/cache.js +189 -189
- package/src/commands/clean.js +80 -80
- package/src/commands/configure.js +92 -92
- package/src/commands/init.js +70 -70
- package/src/commands/install-skill.js +115 -115
- package/src/commands/install.js +730 -674
- package/src/commands/link.js +320 -320
- package/src/commands/profile.js +237 -237
- package/src/commands/publish.js +584 -555
- package/src/commands/show.js +252 -252
- package/src/commands/version.js +187 -0
- package/src/compat.js +273 -273
- package/src/conf/index.js +415 -391
- package/src/conf/namespaces.js +94 -94
- package/src/context.js +230 -230
- package/src/http-fetch.js +53 -53
- package/src/ignore.js +118 -118
- package/src/logger.js +122 -122
- package/src/options.js +303 -303
- package/src/settings-overrides.js +152 -152
- package/src/toolchain/deps.js +164 -164
- package/src/toolchain/index.js +212 -212
- package/src/toolchain/presets.js +356 -340
- package/src/toolchain/template.cmake +77 -77
- package/src/upload-built.js +265 -265
- package/src/version-range.js +301 -301
- package/src/zip-safe.js +52 -52
- package/src/zip-stream.js +126 -0
package/src/bootstrap/detect.js
CHANGED
|
@@ -1,150 +1,150 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const fs = require('fs');
|
|
4
|
-
const path = require('path');
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Inspect a cloned repo directory and infer the wyvrnpm `kind`, plus
|
|
8
|
-
* anything else a bootstrap flow can read off the filesystem cheaply.
|
|
9
|
-
*
|
|
10
|
-
* We explicitly do NOT fully parse CMakeLists.txt — a regex scan is good
|
|
11
|
-
* enough for the 80% case, and the bootstrap command's job is to produce
|
|
12
|
-
* a *first draft* that the human reviews before publish. When the signal
|
|
13
|
-
* is ambiguous we return `unknown` and let the TODO report surface it.
|
|
14
|
-
*
|
|
15
|
-
* @typedef {Object} DetectResult
|
|
16
|
-
* @property {'HeaderOnlyLib' | 'StaticLib' | 'DynamicLib' | 'unknown'} kind
|
|
17
|
-
* @property {boolean} hasCMakeLists — root CMakeLists.txt present?
|
|
18
|
-
* @property {boolean} hasConfigureAc — autotools (libsodium, bzip2)?
|
|
19
|
-
* @property {boolean} hasMeson — meson.build present?
|
|
20
|
-
* @property {string[]} notes — human-readable signals for the TODO report.
|
|
21
|
-
*/
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* @param {string} repoDir
|
|
25
|
-
* @returns {DetectResult}
|
|
26
|
-
*/
|
|
27
|
-
function detectFromRepo(repoDir) {
|
|
28
|
-
const notes = [];
|
|
29
|
-
const result = {
|
|
30
|
-
kind: 'unknown',
|
|
31
|
-
hasCMakeLists: false,
|
|
32
|
-
hasConfigureAc: false,
|
|
33
|
-
hasMeson: false,
|
|
34
|
-
notes,
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
if (!fs.existsSync(repoDir) || !fs.statSync(repoDir).isDirectory()) {
|
|
38
|
-
notes.push(`directory does not exist: ${repoDir}`);
|
|
39
|
-
return result;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const cmakePath = path.join(repoDir, 'CMakeLists.txt');
|
|
43
|
-
result.hasCMakeLists = fs.existsSync(cmakePath);
|
|
44
|
-
result.hasConfigureAc = fs.existsSync(path.join(repoDir, 'configure.ac'))
|
|
45
|
-
|| fs.existsSync(path.join(repoDir, 'configure'));
|
|
46
|
-
result.hasMeson = fs.existsSync(path.join(repoDir, 'meson.build'));
|
|
47
|
-
|
|
48
|
-
if (!result.hasCMakeLists) {
|
|
49
|
-
if (result.hasConfigureAc) {
|
|
50
|
-
notes.push(
|
|
51
|
-
'no CMakeLists.txt — upstream uses autotools. wyvrnpm source-build ' +
|
|
52
|
-
'supports cmake only; ship a wrapper CMakeLists.txt in your fork or ' +
|
|
53
|
-
'prebuild and publish as a binary-only artefact.',
|
|
54
|
-
);
|
|
55
|
-
} else if (result.hasMeson) {
|
|
56
|
-
notes.push(
|
|
57
|
-
'no CMakeLists.txt — upstream uses meson. Same workaround as ' +
|
|
58
|
-
'autotools: ship a wrapper CMakeLists.txt in your fork.',
|
|
59
|
-
);
|
|
60
|
-
} else {
|
|
61
|
-
notes.push(
|
|
62
|
-
'no CMakeLists.txt and no recognised build system — likely a header-' +
|
|
63
|
-
'drop upstream (e.g. imgui, nuklear, stb). Add a small CMakeLists.txt ' +
|
|
64
|
-
'in the fork that declares an INTERFACE target + install() rules.',
|
|
65
|
-
);
|
|
66
|
-
}
|
|
67
|
-
return result;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const kindFromCmake = detectKindFromCMakeLists(cmakePath);
|
|
71
|
-
result.kind = kindFromCmake.kind;
|
|
72
|
-
if (kindFromCmake.note) notes.push(kindFromCmake.note);
|
|
73
|
-
return result;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Scan a CMakeLists.txt for the most specific `add_library(<name> <type>)`
|
|
78
|
-
* signal we can find. In order of preference we look for:
|
|
79
|
-
* INTERFACE → HeaderOnlyLib
|
|
80
|
-
* SHARED → DynamicLib
|
|
81
|
-
* STATIC → StaticLib
|
|
82
|
-
* MODULE → StaticLib (rare; treat as static for now)
|
|
83
|
-
*
|
|
84
|
-
* If we find `add_library(<name>)` with no explicit type, CMake's default
|
|
85
|
-
* depends on `BUILD_SHARED_LIBS`. wyvrnpm's convention is to default to
|
|
86
|
-
* `StaticLib` — the consumer can flip via an `options.shared` toggle later.
|
|
87
|
-
*
|
|
88
|
-
* `add_executable(...)` with no `add_library(...)` → the repo ships only a
|
|
89
|
-
* tool, not a library. We return `unknown` so the TODO report surfaces it.
|
|
90
|
-
*
|
|
91
|
-
* @param {string} cmakePath
|
|
92
|
-
* @returns {{ kind: DetectResult['kind'], note?: string }}
|
|
93
|
-
*/
|
|
94
|
-
function detectKindFromCMakeLists(cmakePath) {
|
|
95
|
-
let text;
|
|
96
|
-
try { text = fs.readFileSync(cmakePath, 'utf8'); }
|
|
97
|
-
catch { return { kind: 'unknown', note: `could not read ${cmakePath}` }; }
|
|
98
|
-
|
|
99
|
-
// Strip line comments so an old "# add_library(foo SHARED ...)" doesn't
|
|
100
|
-
// poison detection. Block comments in CMake (#[[ ... ]]) are rare; not
|
|
101
|
-
// worth handling here.
|
|
102
|
-
const stripped = text.replace(/#[^\n]*/g, '');
|
|
103
|
-
|
|
104
|
-
const has = (re) => re.test(stripped);
|
|
105
|
-
|
|
106
|
-
// add_library(<name> [STATIC|SHARED|MODULE|OBJECT|INTERFACE|IMPORTED] ...)
|
|
107
|
-
if (has(/add_library\s*\(\s*[A-Za-z0-9_.+-]+\s+INTERFACE\b/i)) {
|
|
108
|
-
return { kind: 'HeaderOnlyLib' };
|
|
109
|
-
}
|
|
110
|
-
if (has(/add_library\s*\(\s*[A-Za-z0-9_.+-]+\s+SHARED\b/i)) {
|
|
111
|
-
return {
|
|
112
|
-
kind: 'DynamicLib',
|
|
113
|
-
note: 'detected SHARED library — consider declaring an `options.shared` toggle if the upstream respects BUILD_SHARED_LIBS.',
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
if (has(/add_library\s*\(\s*[A-Za-z0-9_.+-]+\s+STATIC\b/i)) {
|
|
117
|
-
return { kind: 'StaticLib' };
|
|
118
|
-
}
|
|
119
|
-
if (has(/add_library\s*\(\s*[A-Za-z0-9_.+-]+\s+(MODULE|OBJECT)\b/i)) {
|
|
120
|
-
return {
|
|
121
|
-
kind: 'StaticLib',
|
|
122
|
-
note: 'detected MODULE/OBJECT library — treating as StaticLib. Review.',
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
// Implicit-default form: `add_library(<name> <sources>...)` — no type
|
|
126
|
-
// keyword after the name. Negative lookahead on the recognised types
|
|
127
|
-
// distinguishes this from the explicit-type cases above (which we've
|
|
128
|
-
// already checked and returned from).
|
|
129
|
-
if (has(/add_library\s*\(\s*[A-Za-z0-9_.+-]+\s+(?!(STATIC|SHARED|MODULE|OBJECT|INTERFACE|IMPORTED)\b)/i)) {
|
|
130
|
-
return {
|
|
131
|
-
kind: 'StaticLib',
|
|
132
|
-
note: 'add_library() with no explicit type — defaulting to StaticLib. ' +
|
|
133
|
-
'If the upstream respects BUILD_SHARED_LIBS, add an `options.shared` toggle.',
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
if (has(/add_executable\s*\(/i)) {
|
|
137
|
-
return {
|
|
138
|
-
kind: 'unknown',
|
|
139
|
-
note: 'repo declares add_executable() but no add_library() — looks like ' +
|
|
140
|
-
'a tool, not a library. Set kind: ConsoleApp in the manifest.',
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
return {
|
|
144
|
-
kind: 'unknown',
|
|
145
|
-
note: 'no add_library() / add_executable() found at the root CMakeLists.txt. ' +
|
|
146
|
-
'The library may be declared in a subdirectory — inspect and set kind manually.',
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
module.exports = { detectFromRepo, detectKindFromCMakeLists };
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Inspect a cloned repo directory and infer the wyvrnpm `kind`, plus
|
|
8
|
+
* anything else a bootstrap flow can read off the filesystem cheaply.
|
|
9
|
+
*
|
|
10
|
+
* We explicitly do NOT fully parse CMakeLists.txt — a regex scan is good
|
|
11
|
+
* enough for the 80% case, and the bootstrap command's job is to produce
|
|
12
|
+
* a *first draft* that the human reviews before publish. When the signal
|
|
13
|
+
* is ambiguous we return `unknown` and let the TODO report surface it.
|
|
14
|
+
*
|
|
15
|
+
* @typedef {Object} DetectResult
|
|
16
|
+
* @property {'HeaderOnlyLib' | 'StaticLib' | 'DynamicLib' | 'unknown'} kind
|
|
17
|
+
* @property {boolean} hasCMakeLists — root CMakeLists.txt present?
|
|
18
|
+
* @property {boolean} hasConfigureAc — autotools (libsodium, bzip2)?
|
|
19
|
+
* @property {boolean} hasMeson — meson.build present?
|
|
20
|
+
* @property {string[]} notes — human-readable signals for the TODO report.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @param {string} repoDir
|
|
25
|
+
* @returns {DetectResult}
|
|
26
|
+
*/
|
|
27
|
+
function detectFromRepo(repoDir) {
|
|
28
|
+
const notes = [];
|
|
29
|
+
const result = {
|
|
30
|
+
kind: 'unknown',
|
|
31
|
+
hasCMakeLists: false,
|
|
32
|
+
hasConfigureAc: false,
|
|
33
|
+
hasMeson: false,
|
|
34
|
+
notes,
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
if (!fs.existsSync(repoDir) || !fs.statSync(repoDir).isDirectory()) {
|
|
38
|
+
notes.push(`directory does not exist: ${repoDir}`);
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const cmakePath = path.join(repoDir, 'CMakeLists.txt');
|
|
43
|
+
result.hasCMakeLists = fs.existsSync(cmakePath);
|
|
44
|
+
result.hasConfigureAc = fs.existsSync(path.join(repoDir, 'configure.ac'))
|
|
45
|
+
|| fs.existsSync(path.join(repoDir, 'configure'));
|
|
46
|
+
result.hasMeson = fs.existsSync(path.join(repoDir, 'meson.build'));
|
|
47
|
+
|
|
48
|
+
if (!result.hasCMakeLists) {
|
|
49
|
+
if (result.hasConfigureAc) {
|
|
50
|
+
notes.push(
|
|
51
|
+
'no CMakeLists.txt — upstream uses autotools. wyvrnpm source-build ' +
|
|
52
|
+
'supports cmake only; ship a wrapper CMakeLists.txt in your fork or ' +
|
|
53
|
+
'prebuild and publish as a binary-only artefact.',
|
|
54
|
+
);
|
|
55
|
+
} else if (result.hasMeson) {
|
|
56
|
+
notes.push(
|
|
57
|
+
'no CMakeLists.txt — upstream uses meson. Same workaround as ' +
|
|
58
|
+
'autotools: ship a wrapper CMakeLists.txt in your fork.',
|
|
59
|
+
);
|
|
60
|
+
} else {
|
|
61
|
+
notes.push(
|
|
62
|
+
'no CMakeLists.txt and no recognised build system — likely a header-' +
|
|
63
|
+
'drop upstream (e.g. imgui, nuklear, stb). Add a small CMakeLists.txt ' +
|
|
64
|
+
'in the fork that declares an INTERFACE target + install() rules.',
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
return result;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const kindFromCmake = detectKindFromCMakeLists(cmakePath);
|
|
71
|
+
result.kind = kindFromCmake.kind;
|
|
72
|
+
if (kindFromCmake.note) notes.push(kindFromCmake.note);
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Scan a CMakeLists.txt for the most specific `add_library(<name> <type>)`
|
|
78
|
+
* signal we can find. In order of preference we look for:
|
|
79
|
+
* INTERFACE → HeaderOnlyLib
|
|
80
|
+
* SHARED → DynamicLib
|
|
81
|
+
* STATIC → StaticLib
|
|
82
|
+
* MODULE → StaticLib (rare; treat as static for now)
|
|
83
|
+
*
|
|
84
|
+
* If we find `add_library(<name>)` with no explicit type, CMake's default
|
|
85
|
+
* depends on `BUILD_SHARED_LIBS`. wyvrnpm's convention is to default to
|
|
86
|
+
* `StaticLib` — the consumer can flip via an `options.shared` toggle later.
|
|
87
|
+
*
|
|
88
|
+
* `add_executable(...)` with no `add_library(...)` → the repo ships only a
|
|
89
|
+
* tool, not a library. We return `unknown` so the TODO report surfaces it.
|
|
90
|
+
*
|
|
91
|
+
* @param {string} cmakePath
|
|
92
|
+
* @returns {{ kind: DetectResult['kind'], note?: string }}
|
|
93
|
+
*/
|
|
94
|
+
function detectKindFromCMakeLists(cmakePath) {
|
|
95
|
+
let text;
|
|
96
|
+
try { text = fs.readFileSync(cmakePath, 'utf8'); }
|
|
97
|
+
catch { return { kind: 'unknown', note: `could not read ${cmakePath}` }; }
|
|
98
|
+
|
|
99
|
+
// Strip line comments so an old "# add_library(foo SHARED ...)" doesn't
|
|
100
|
+
// poison detection. Block comments in CMake (#[[ ... ]]) are rare; not
|
|
101
|
+
// worth handling here.
|
|
102
|
+
const stripped = text.replace(/#[^\n]*/g, '');
|
|
103
|
+
|
|
104
|
+
const has = (re) => re.test(stripped);
|
|
105
|
+
|
|
106
|
+
// add_library(<name> [STATIC|SHARED|MODULE|OBJECT|INTERFACE|IMPORTED] ...)
|
|
107
|
+
if (has(/add_library\s*\(\s*[A-Za-z0-9_.+-]+\s+INTERFACE\b/i)) {
|
|
108
|
+
return { kind: 'HeaderOnlyLib' };
|
|
109
|
+
}
|
|
110
|
+
if (has(/add_library\s*\(\s*[A-Za-z0-9_.+-]+\s+SHARED\b/i)) {
|
|
111
|
+
return {
|
|
112
|
+
kind: 'DynamicLib',
|
|
113
|
+
note: 'detected SHARED library — consider declaring an `options.shared` toggle if the upstream respects BUILD_SHARED_LIBS.',
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
if (has(/add_library\s*\(\s*[A-Za-z0-9_.+-]+\s+STATIC\b/i)) {
|
|
117
|
+
return { kind: 'StaticLib' };
|
|
118
|
+
}
|
|
119
|
+
if (has(/add_library\s*\(\s*[A-Za-z0-9_.+-]+\s+(MODULE|OBJECT)\b/i)) {
|
|
120
|
+
return {
|
|
121
|
+
kind: 'StaticLib',
|
|
122
|
+
note: 'detected MODULE/OBJECT library — treating as StaticLib. Review.',
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
// Implicit-default form: `add_library(<name> <sources>...)` — no type
|
|
126
|
+
// keyword after the name. Negative lookahead on the recognised types
|
|
127
|
+
// distinguishes this from the explicit-type cases above (which we've
|
|
128
|
+
// already checked and returned from).
|
|
129
|
+
if (has(/add_library\s*\(\s*[A-Za-z0-9_.+-]+\s+(?!(STATIC|SHARED|MODULE|OBJECT|INTERFACE|IMPORTED)\b)/i)) {
|
|
130
|
+
return {
|
|
131
|
+
kind: 'StaticLib',
|
|
132
|
+
note: 'add_library() with no explicit type — defaulting to StaticLib. ' +
|
|
133
|
+
'If the upstream respects BUILD_SHARED_LIBS, add an `options.shared` toggle.',
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
if (has(/add_executable\s*\(/i)) {
|
|
137
|
+
return {
|
|
138
|
+
kind: 'unknown',
|
|
139
|
+
note: 'repo declares add_executable() but no add_library() — looks like ' +
|
|
140
|
+
'a tool, not a library. Set kind: ConsoleApp in the manifest.',
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
return {
|
|
144
|
+
kind: 'unknown',
|
|
145
|
+
note: 'no add_library() / add_executable() found at the root CMakeLists.txt. ' +
|
|
146
|
+
'The library may be declared in a subdirectory — inspect and set kind manually.',
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
module.exports = { detectFromRepo, detectKindFromCMakeLists };
|