wyvrnpm 2.11.0 → 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 -1905
- package/bin/{wyvrn.js → wyvrnpm.js} +31 -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 -187
- 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/auth.js
CHANGED
|
@@ -1,66 +1,66 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Resolve an authentication token for HTTP-source reads/writes.
|
|
5
|
-
*
|
|
6
|
-
* Closes EVALUATION.md S8 — passing `--token <value>` on the command line
|
|
7
|
-
* leaks the token into any shell history, process table, or CI job log
|
|
8
|
-
* that captures argv. `--token-env <VAR>` and the config equivalent
|
|
9
|
-
* `tokenEnv` let users keep the literal value in env only.
|
|
10
|
-
*
|
|
11
|
-
* Resolution order (first match wins):
|
|
12
|
-
* 1. `token` — literal string from CLI or config (explicit beats env).
|
|
13
|
-
* 2. `tokenEnv` — name of an env var; its value becomes the token.
|
|
14
|
-
*
|
|
15
|
-
* Returns `undefined` when nothing is configured (valid — not every source
|
|
16
|
-
* needs auth). Throws when `tokenEnv` names a var that is unset or empty.
|
|
17
|
-
*
|
|
18
|
-
* @param {{ token?: string, tokenEnv?: string }} opts
|
|
19
|
-
* @returns {string|undefined}
|
|
20
|
-
*/
|
|
21
|
-
function resolveToken(opts = {}) {
|
|
22
|
-
const { token, tokenEnv } = opts;
|
|
23
|
-
|
|
24
|
-
if (typeof token === 'string' && token.length > 0) {
|
|
25
|
-
return token;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
if (typeof tokenEnv === 'string' && tokenEnv.length > 0) {
|
|
29
|
-
const value = process.env[tokenEnv];
|
|
30
|
-
if (typeof value !== 'string' || value.length === 0) {
|
|
31
|
-
throw new Error(
|
|
32
|
-
`--token-env ${tokenEnv} (or config tokenEnv=${tokenEnv}) is set, ` +
|
|
33
|
-
`but the environment variable is unset or empty.`,
|
|
34
|
-
);
|
|
35
|
-
}
|
|
36
|
-
return value;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return undefined;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Merge CLI auth args + a source-config entry into a final `{ token }`
|
|
44
|
-
* object ready for passing to a provider. Centralises the "CLI wins,
|
|
45
|
-
* then env-backed CLI, then config literal, then config env-backed"
|
|
46
|
-
* precedence so call sites don't each re-implement it.
|
|
47
|
-
*
|
|
48
|
-
* @param {{ token?: string, tokenEnv?: string }} cli
|
|
49
|
-
* @param {{ token?: string, tokenEnv?: string } | null | undefined} source
|
|
50
|
-
* @returns {{ token: string|undefined }}
|
|
51
|
-
*/
|
|
52
|
-
function resolveSourceAuth(cli, source) {
|
|
53
|
-
// Try CLI first; if it produced nothing, fall back to the source's
|
|
54
|
-
// own stored auth. Each call to resolveToken handles its own
|
|
55
|
-
// precedence (literal > env) and throws on invalid tokenEnv.
|
|
56
|
-
const fromCli = resolveToken(cli);
|
|
57
|
-
if (fromCli !== undefined) return { token: fromCli };
|
|
58
|
-
|
|
59
|
-
const fromSource = source ? resolveToken(source) : undefined;
|
|
60
|
-
return { token: fromSource };
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
module.exports = {
|
|
64
|
-
resolveToken,
|
|
65
|
-
resolveSourceAuth,
|
|
66
|
-
};
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Resolve an authentication token for HTTP-source reads/writes.
|
|
5
|
+
*
|
|
6
|
+
* Closes EVALUATION.md S8 — passing `--token <value>` on the command line
|
|
7
|
+
* leaks the token into any shell history, process table, or CI job log
|
|
8
|
+
* that captures argv. `--token-env <VAR>` and the config equivalent
|
|
9
|
+
* `tokenEnv` let users keep the literal value in env only.
|
|
10
|
+
*
|
|
11
|
+
* Resolution order (first match wins):
|
|
12
|
+
* 1. `token` — literal string from CLI or config (explicit beats env).
|
|
13
|
+
* 2. `tokenEnv` — name of an env var; its value becomes the token.
|
|
14
|
+
*
|
|
15
|
+
* Returns `undefined` when nothing is configured (valid — not every source
|
|
16
|
+
* needs auth). Throws when `tokenEnv` names a var that is unset or empty.
|
|
17
|
+
*
|
|
18
|
+
* @param {{ token?: string, tokenEnv?: string }} opts
|
|
19
|
+
* @returns {string|undefined}
|
|
20
|
+
*/
|
|
21
|
+
function resolveToken(opts = {}) {
|
|
22
|
+
const { token, tokenEnv } = opts;
|
|
23
|
+
|
|
24
|
+
if (typeof token === 'string' && token.length > 0) {
|
|
25
|
+
return token;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (typeof tokenEnv === 'string' && tokenEnv.length > 0) {
|
|
29
|
+
const value = process.env[tokenEnv];
|
|
30
|
+
if (typeof value !== 'string' || value.length === 0) {
|
|
31
|
+
throw new Error(
|
|
32
|
+
`--token-env ${tokenEnv} (or config tokenEnv=${tokenEnv}) is set, ` +
|
|
33
|
+
`but the environment variable is unset or empty.`,
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
return value;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Merge CLI auth args + a source-config entry into a final `{ token }`
|
|
44
|
+
* object ready for passing to a provider. Centralises the "CLI wins,
|
|
45
|
+
* then env-backed CLI, then config literal, then config env-backed"
|
|
46
|
+
* precedence so call sites don't each re-implement it.
|
|
47
|
+
*
|
|
48
|
+
* @param {{ token?: string, tokenEnv?: string }} cli
|
|
49
|
+
* @param {{ token?: string, tokenEnv?: string } | null | undefined} source
|
|
50
|
+
* @returns {{ token: string|undefined }}
|
|
51
|
+
*/
|
|
52
|
+
function resolveSourceAuth(cli, source) {
|
|
53
|
+
// Try CLI first; if it produced nothing, fall back to the source's
|
|
54
|
+
// own stored auth. Each call to resolveToken handles its own
|
|
55
|
+
// precedence (literal > env) and throws on invalid tokenEnv.
|
|
56
|
+
const fromCli = resolveToken(cli);
|
|
57
|
+
if (fromCli !== undefined) return { token: fromCli };
|
|
58
|
+
|
|
59
|
+
const fromSource = source ? resolveToken(source) : undefined;
|
|
60
|
+
return { token: fromSource };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
module.exports = {
|
|
64
|
+
resolveToken,
|
|
65
|
+
resolveSourceAuth,
|
|
66
|
+
};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Project-local CMake binary-dir root. Sibling concept to `conf` —
|
|
4
|
+
// non-ABI, dev-local, never published. Two channels feed it:
|
|
5
|
+
//
|
|
6
|
+
// 1. CLI flag `--build-dir <path>` (install + build)
|
|
7
|
+
// 2. wyvrn.local.json `binaryDirRoot` (persistent per-developer)
|
|
8
|
+
//
|
|
9
|
+
// CLI > local > default `"build"`. The resolved value plugs into the
|
|
10
|
+
// preset's binaryDir as `${sourceDir}/<binaryDirRoot>/wyvrn-<profile>`.
|
|
11
|
+
//
|
|
12
|
+
// Why this exists: repos with a `BUILD` Bazel/Buck file at the root
|
|
13
|
+
// collide with the default `build/` subdir on case-insensitive
|
|
14
|
+
// filesystems (Windows NTFS, macOS HFS+ default). gRPC is the
|
|
15
|
+
// canonical case.
|
|
16
|
+
|
|
17
|
+
const path = require('path');
|
|
18
|
+
|
|
19
|
+
const DEFAULT_BINARY_DIR_ROOT = 'build';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Validate + normalise a candidate binaryDirRoot value. Returns the
|
|
23
|
+
* normalised string (forward slashes, no trailing separator) or
|
|
24
|
+
* throws with a `<source>:` prefix so the caller knows which channel
|
|
25
|
+
* the bad value came from.
|
|
26
|
+
*
|
|
27
|
+
* @param {unknown} value
|
|
28
|
+
* @param {string} source e.g. "--build-dir" or "wyvrn.local.json"
|
|
29
|
+
* @returns {string}
|
|
30
|
+
*/
|
|
31
|
+
function validateBinaryDirRoot(value, source) {
|
|
32
|
+
if (typeof value !== 'string') {
|
|
33
|
+
throw new Error(`${source}: binaryDirRoot must be a string, got ${typeof value}`);
|
|
34
|
+
}
|
|
35
|
+
const trimmed = value.trim();
|
|
36
|
+
if (trimmed.length === 0) {
|
|
37
|
+
throw new Error(`${source}: binaryDirRoot must not be empty`);
|
|
38
|
+
}
|
|
39
|
+
// Reject absolute paths — the preset macro is `${sourceDir}/<root>`,
|
|
40
|
+
// so an absolute value would produce nonsense (`${sourceDir}//abs`
|
|
41
|
+
// or `${sourceDir}/C:/...`). If a user genuinely wants an absolute
|
|
42
|
+
// build dir they can hand-edit CMakeUserPresets.json; that's a
|
|
43
|
+
// different escape hatch.
|
|
44
|
+
if (path.isAbsolute(trimmed) || /^[a-zA-Z]:[\\/]/.test(trimmed)) {
|
|
45
|
+
throw new Error(
|
|
46
|
+
`${source}: binaryDirRoot must be relative to the project root, ` +
|
|
47
|
+
`got ${JSON.stringify(trimmed)}`,
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Normalise to forward slashes (CMake preset macros expect them) and
|
|
52
|
+
// strip any trailing separators so the join is deterministic.
|
|
53
|
+
const normalised = trimmed.replace(/\\/g, '/').replace(/\/+$/, '');
|
|
54
|
+
if (normalised.length === 0) {
|
|
55
|
+
throw new Error(`${source}: binaryDirRoot must not be empty`);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// `..` segments would let a value escape the project root — reject
|
|
59
|
+
// rather than silently allow it. Single `.` segments are harmless and
|
|
60
|
+
// CMake handles them fine.
|
|
61
|
+
if (normalised.split('/').some((seg) => seg === '..')) {
|
|
62
|
+
throw new Error(`${source}: binaryDirRoot must not contain ".." segments`);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return normalised;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Resolve the effective binaryDirRoot from the two configured channels.
|
|
70
|
+
* Pure function — deliberately takes pre-read values rather than doing
|
|
71
|
+
* filesystem I/O so unit tests don't need temp dirs.
|
|
72
|
+
*
|
|
73
|
+
* @param {object} args
|
|
74
|
+
* @param {string|null|undefined} [args.cliBuildDir]
|
|
75
|
+
* Value of `--build-dir` from argv. `undefined`/`null` = not passed.
|
|
76
|
+
* @param {string|null|undefined} [args.localOverlayBinaryDirRoot]
|
|
77
|
+
* Value of `binaryDirRoot` read out of wyvrn.local.json (already
|
|
78
|
+
* parsed; this module does NOT re-read the file).
|
|
79
|
+
* @returns {string}
|
|
80
|
+
*/
|
|
81
|
+
function resolveBinaryDirRoot({ cliBuildDir, localOverlayBinaryDirRoot } = {}) {
|
|
82
|
+
if (cliBuildDir !== undefined && cliBuildDir !== null) {
|
|
83
|
+
return validateBinaryDirRoot(cliBuildDir, '--build-dir');
|
|
84
|
+
}
|
|
85
|
+
if (localOverlayBinaryDirRoot !== undefined && localOverlayBinaryDirRoot !== null) {
|
|
86
|
+
return validateBinaryDirRoot(localOverlayBinaryDirRoot, 'wyvrn.local.json');
|
|
87
|
+
}
|
|
88
|
+
return DEFAULT_BINARY_DIR_ROOT;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
module.exports = {
|
|
92
|
+
DEFAULT_BINARY_DIR_ROOT,
|
|
93
|
+
resolveBinaryDirRoot,
|
|
94
|
+
validateBinaryDirRoot,
|
|
95
|
+
};
|
|
@@ -1,196 +1,196 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Known-library cookbook for `wyvrnpm bootstrap`.
|
|
5
|
-
*
|
|
6
|
-
* Each entry captures the non-obvious tweaks a wyvrnpm recipe needs for a
|
|
7
|
-
* popular upstream — the CMake cache variables that disable tests /
|
|
8
|
-
* examples / docs so the install tree doesn't balloon, install gates the
|
|
9
|
-
* upstream hides behind a flag (the `ZLIB_INSTALL=ON` class of gotcha,
|
|
10
|
-
* see SKILL.md references/manifest-authoring.md §build), and any
|
|
11
|
-
* transitive wyvrnpm deps the upstream already depends on.
|
|
12
|
-
*
|
|
13
|
-
* Keyed by a case-insensitive match on the repo tail. Matching is
|
|
14
|
-
* restricted to exact tails so `wyvrnpm bootstrap` never surprises a
|
|
15
|
-
* user whose fork name collides coincidentally — unmatched tails get
|
|
16
|
-
* the safe-default recipe.
|
|
17
|
-
*
|
|
18
|
-
* Keep this file short and dumb. Rich per-library behaviour belongs in
|
|
19
|
-
* the author's actual `wyvrn.json` — the cookbook is just the "everyone
|
|
20
|
-
* hits these flags on day one" cheat sheet.
|
|
21
|
-
*
|
|
22
|
-
* @typedef {Object} CookbookEntry
|
|
23
|
-
* @property {'HeaderOnlyLib'|'StaticLib'|'DynamicLib'} [kind]
|
|
24
|
-
* Override `detect.js` when upstream's CMakeLists lies (e.g. fmt has
|
|
25
|
-
* both a STATIC lib and an INTERFACE `fmt-header-only`).
|
|
26
|
-
* @property {string[]} [configure]
|
|
27
|
-
* `-DKEY=VAL` args threaded into build.configure. Preserves order so a
|
|
28
|
-
* `-DBUILD_SHARED_LIBS=OFF` comes before a `-DXYZ_OPTION=...` override.
|
|
29
|
-
* @property {Record<string,string>} [dependencies]
|
|
30
|
-
* Known wyvrnpm deps — merged into manifest.dependencies. Versions
|
|
31
|
-
* use `"latest"` so the user picks up whatever the team's registry
|
|
32
|
-
* publishes; they can pin in review.
|
|
33
|
-
* @property {string[]} [notes]
|
|
34
|
-
* Human-readable reminders appended to the TODO report.
|
|
35
|
-
*/
|
|
36
|
-
|
|
37
|
-
/** @type {Record<string, CookbookEntry>} */
|
|
38
|
-
const KNOWN_LIBRARIES = Object.freeze({
|
|
39
|
-
// ── Formatting / logging ─────────────────────────────────────────────
|
|
40
|
-
fmt: {
|
|
41
|
-
kind: 'StaticLib',
|
|
42
|
-
configure: ['-DFMT_TEST=OFF', '-DFMT_DOC=OFF'],
|
|
43
|
-
notes: [
|
|
44
|
-
'fmt also ships a `fmt-header-only` INTERFACE target. If you want ' +
|
|
45
|
-
'the header-only variant, declare kind=HeaderOnlyLib and add -DFMT_INSTALL=ON.',
|
|
46
|
-
],
|
|
47
|
-
},
|
|
48
|
-
spdlog: {
|
|
49
|
-
kind: 'StaticLib',
|
|
50
|
-
configure: [
|
|
51
|
-
'-DSPDLOG_BUILD_TESTS=OFF',
|
|
52
|
-
'-DSPDLOG_BUILD_EXAMPLE=OFF',
|
|
53
|
-
'-DSPDLOG_INSTALL=ON',
|
|
54
|
-
'-DSPDLOG_FMT_EXTERNAL=ON',
|
|
55
|
-
],
|
|
56
|
-
dependencies: { fmt: 'latest' },
|
|
57
|
-
notes: [
|
|
58
|
-
'SPDLOG_FMT_EXTERNAL=ON makes spdlog link against the wyvrnpm fmt package ' +
|
|
59
|
-
'instead of its bundled fork. Drop if you want the bundled copy.',
|
|
60
|
-
],
|
|
61
|
-
},
|
|
62
|
-
|
|
63
|
-
// ── JSON / config / serialization ────────────────────────────────────
|
|
64
|
-
json: { kind: 'HeaderOnlyLib', configure: ['-DJSON_BuildTests=OFF'] },
|
|
65
|
-
rapidjson: { kind: 'HeaderOnlyLib', configure: ['-DRAPIDJSON_BUILD_TESTS=OFF', '-DRAPIDJSON_BUILD_EXAMPLES=OFF', '-DRAPIDJSON_BUILD_DOC=OFF'] },
|
|
66
|
-
jsoncpp: { kind: 'StaticLib', configure: ['-DJSONCPP_WITH_TESTS=OFF', '-DJSONCPP_WITH_POST_BUILD_UNITTEST=OFF'] },
|
|
67
|
-
'yaml-cpp':{ kind: 'StaticLib', configure: ['-DYAML_CPP_BUILD_TESTS=OFF', '-DYAML_CPP_BUILD_TOOLS=OFF', '-DYAML_CPP_INSTALL=ON'] },
|
|
68
|
-
pugixml: { kind: 'StaticLib', configure: ['-DPUGIXML_BUILD_TESTS=OFF'] },
|
|
69
|
-
tinyxml2: { kind: 'StaticLib', configure: ['-Dtinyxml2_BUILD_TESTING=OFF'] },
|
|
70
|
-
cereal: { kind: 'HeaderOnlyLib', configure: ['-DJUST_INSTALL_CEREAL=ON'] },
|
|
71
|
-
'msgpack-c': { kind: 'StaticLib', configure: ['-DMSGPACK_BUILD_TESTS=OFF', '-DMSGPACK_BUILD_EXAMPLES=OFF'] },
|
|
72
|
-
|
|
73
|
-
// ── CLI / utilities ──────────────────────────────────────────────────
|
|
74
|
-
cli11: { kind: 'HeaderOnlyLib', configure: ['-DCLI11_BUILD_TESTS=OFF', '-DCLI11_BUILD_EXAMPLES=OFF'] },
|
|
75
|
-
cxxopts: { kind: 'HeaderOnlyLib', configure: ['-DCXXOPTS_BUILD_TESTS=OFF', '-DCXXOPTS_BUILD_EXAMPLES=OFF'] },
|
|
76
|
-
magic_enum: { kind: 'HeaderOnlyLib', configure: ['-DMAGIC_ENUM_OPT_BUILD_EXAMPLES=OFF', '-DMAGIC_ENUM_OPT_BUILD_TESTS=OFF'] },
|
|
77
|
-
date: { kind: 'StaticLib', configure: ['-DBUILD_TZ_LIB=ON', '-DUSE_SYSTEM_TZ_DB=OFF'] },
|
|
78
|
-
utfcpp: { kind: 'HeaderOnlyLib', configure: ['-DUTF8_TESTS=OFF', '-DUTF8_SAMPLES=OFF'] },
|
|
79
|
-
|
|
80
|
-
// ── Testing / benchmarking ──────────────────────────────────────────
|
|
81
|
-
catch2: { kind: 'StaticLib', configure: ['-DCATCH_INSTALL_DOCS=OFF', '-DCATCH_BUILD_TESTING=OFF'] },
|
|
82
|
-
doctest: { kind: 'HeaderOnlyLib', configure: ['-DDOCTEST_WITH_TESTS=OFF', '-DDOCTEST_WITH_MAIN_IN_STATIC_LIB=OFF'] },
|
|
83
|
-
benchmark: {
|
|
84
|
-
kind: 'StaticLib',
|
|
85
|
-
configure: ['-DBENCHMARK_ENABLE_TESTING=OFF', '-DBENCHMARK_ENABLE_GTEST_TESTS=OFF'],
|
|
86
|
-
notes: ['google/benchmark — only one of several projects named "benchmark"; confirm the repo URL.'],
|
|
87
|
-
},
|
|
88
|
-
|
|
89
|
-
// ── Compression ──────────────────────────────────────────────────────
|
|
90
|
-
zlib: {
|
|
91
|
-
kind: 'StaticLib',
|
|
92
|
-
configure: ['-DZLIB_BUILD_EXAMPLES=OFF'],
|
|
93
|
-
notes: [
|
|
94
|
-
'zlib is the textbook example for an `options.shared` toggle — see ' +
|
|
95
|
-
'references/worked-example-zlib.md. Consider declaring it before you publish.',
|
|
96
|
-
],
|
|
97
|
-
},
|
|
98
|
-
lz4: { kind: 'StaticLib', configure: ['-DLZ4_BUILD_LEGACY_LZ4C=OFF', '-DLZ4_BUILD_CLI=OFF', '-DBUILD_SHARED_LIBS=OFF'] },
|
|
99
|
-
snappy: { kind: 'StaticLib', configure: ['-DSNAPPY_BUILD_TESTS=OFF', '-DSNAPPY_BUILD_BENCHMARKS=OFF'] },
|
|
100
|
-
brotli: { kind: 'StaticLib', configure: ['-DBROTLI_DISABLE_TESTS=ON'] },
|
|
101
|
-
bzip2: {
|
|
102
|
-
notes: [
|
|
103
|
-
'bzip2 uses autotools (no CMakeLists.txt). Either ship a wrapper CMakeLists.txt ' +
|
|
104
|
-
'in your fork or prebuild + publish as a binary-only artefact.',
|
|
105
|
-
],
|
|
106
|
-
},
|
|
107
|
-
|
|
108
|
-
// ── Networking / HTTP ────────────────────────────────────────────────
|
|
109
|
-
'cpp-httplib': { kind: 'HeaderOnlyLib', configure: ['-DHTTPLIB_TEST=OFF'] },
|
|
110
|
-
cpr: {
|
|
111
|
-
kind: 'StaticLib',
|
|
112
|
-
configure: ['-DCPR_BUILD_TESTS=OFF', '-DCPR_USE_SYSTEM_CURL=ON'],
|
|
113
|
-
notes: ['cpr needs libcurl — add a wyvrnpm `libcurl` dep if your registry publishes one, or rely on system curl.'],
|
|
114
|
-
},
|
|
115
|
-
websocketpp: {
|
|
116
|
-
kind: 'HeaderOnlyLib',
|
|
117
|
-
notes: ['websocketpp requires boost::asio or standalone Asio — add the appropriate dep.'],
|
|
118
|
-
},
|
|
119
|
-
cppzmq: {
|
|
120
|
-
kind: 'HeaderOnlyLib',
|
|
121
|
-
notes: ['cppzmq needs libzmq — add a wyvrnpm dep for libzmq before publish.'],
|
|
122
|
-
},
|
|
123
|
-
hiredis: { kind: 'StaticLib', configure: ['-DDISABLE_TESTS=ON', '-DENABLE_EXAMPLES=OFF'] },
|
|
124
|
-
'redis-plus-plus': {
|
|
125
|
-
kind: 'StaticLib',
|
|
126
|
-
configure: ['-DREDIS_PLUS_PLUS_BUILD_TEST=OFF', '-DREDIS_PLUS_PLUS_USE_TLS=OFF'],
|
|
127
|
-
dependencies: { hiredis: 'latest' },
|
|
128
|
-
},
|
|
129
|
-
|
|
130
|
-
// ── Concurrency ──────────────────────────────────────────────────────
|
|
131
|
-
concurrentqueue: { kind: 'HeaderOnlyLib' },
|
|
132
|
-
readerwriterqueue: { kind: 'HeaderOnlyLib' },
|
|
133
|
-
|
|
134
|
-
// ── Graphics / image ─────────────────────────────────────────────────
|
|
135
|
-
stb: {
|
|
136
|
-
kind: 'HeaderOnlyLib',
|
|
137
|
-
notes: [
|
|
138
|
-
'stb is a header drop — no CMakeLists.txt upstream. Ship a small wrapper ' +
|
|
139
|
-
'CMakeLists.txt in your fork that declares an INTERFACE target with ' +
|
|
140
|
-
'target_include_directories(... INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) and install() rules.',
|
|
141
|
-
],
|
|
142
|
-
},
|
|
143
|
-
glm: { kind: 'HeaderOnlyLib', configure: ['-DGLM_TEST_ENABLE=OFF', '-DGLM_BUILD_LIBRARY=OFF'] },
|
|
144
|
-
imgui: {
|
|
145
|
-
notes: [
|
|
146
|
-
'imgui ships no CMakeLists.txt. Ship a wrapper CMakeLists.txt in your fork ' +
|
|
147
|
-
'that picks the backends you need (OpenGL3/Win32/DX11/etc) and declares a ' +
|
|
148
|
-
'StaticLib with them.',
|
|
149
|
-
],
|
|
150
|
-
},
|
|
151
|
-
nuklear: {
|
|
152
|
-
kind: 'HeaderOnlyLib',
|
|
153
|
-
notes: [
|
|
154
|
-
'Nuklear is a single-header drop. Same pattern as stb: ship an INTERFACE ' +
|
|
155
|
-
'wrapper CMakeLists.txt in your fork.',
|
|
156
|
-
],
|
|
157
|
-
},
|
|
158
|
-
|
|
159
|
-
// ── Database ─────────────────────────────────────────────────────────
|
|
160
|
-
sqlitecpp: { kind: 'StaticLib', configure: ['-DSQLITECPP_RUN_CPPLINT=OFF', '-DSQLITECPP_RUN_CPPCHECK=OFF', '-DSQLITECPP_BUILD_TESTS=OFF', '-DSQLITECPP_BUILD_EXAMPLES=OFF'] },
|
|
161
|
-
|
|
162
|
-
// ── Crypto ───────────────────────────────────────────────────────────
|
|
163
|
-
libsodium: {
|
|
164
|
-
notes: [
|
|
165
|
-
'libsodium uses autotools (configure.ac, Makefile.am). wyvrnpm source-build ' +
|
|
166
|
-
'supports cmake only — ship a wrapper CMakeLists.txt in your fork, or ' +
|
|
167
|
-
'prebuild + publish as a binary-only artefact.',
|
|
168
|
-
],
|
|
169
|
-
},
|
|
170
|
-
|
|
171
|
-
// ── Text / regex ─────────────────────────────────────────────────────
|
|
172
|
-
re2: { kind: 'StaticLib', configure: ['-DRE2_BUILD_TESTING=OFF'] },
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* Look up cookbook hints for a given package tail (e.g. "fmt", "zlib").
|
|
177
|
-
* Case-insensitive; returns a defensive copy so callers can merge freely.
|
|
178
|
-
*
|
|
179
|
-
* @param {string} key
|
|
180
|
-
* @returns {CookbookEntry | null}
|
|
181
|
-
*/
|
|
182
|
-
function lookupCookbook(key) {
|
|
183
|
-
if (typeof key !== 'string') return null;
|
|
184
|
-
const normal = key.trim().toLowerCase();
|
|
185
|
-
if (!normal) return null;
|
|
186
|
-
const entry = KNOWN_LIBRARIES[normal];
|
|
187
|
-
if (!entry) return null;
|
|
188
|
-
return {
|
|
189
|
-
...entry,
|
|
190
|
-
configure: entry.configure ? [...entry.configure] : undefined,
|
|
191
|
-
dependencies: entry.dependencies ? { ...entry.dependencies } : undefined,
|
|
192
|
-
notes: entry.notes ? [...entry.notes] : undefined,
|
|
193
|
-
};
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
module.exports = { KNOWN_LIBRARIES, lookupCookbook };
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Known-library cookbook for `wyvrnpm bootstrap`.
|
|
5
|
+
*
|
|
6
|
+
* Each entry captures the non-obvious tweaks a wyvrnpm recipe needs for a
|
|
7
|
+
* popular upstream — the CMake cache variables that disable tests /
|
|
8
|
+
* examples / docs so the install tree doesn't balloon, install gates the
|
|
9
|
+
* upstream hides behind a flag (the `ZLIB_INSTALL=ON` class of gotcha,
|
|
10
|
+
* see SKILL.md references/manifest-authoring.md §build), and any
|
|
11
|
+
* transitive wyvrnpm deps the upstream already depends on.
|
|
12
|
+
*
|
|
13
|
+
* Keyed by a case-insensitive match on the repo tail. Matching is
|
|
14
|
+
* restricted to exact tails so `wyvrnpm bootstrap` never surprises a
|
|
15
|
+
* user whose fork name collides coincidentally — unmatched tails get
|
|
16
|
+
* the safe-default recipe.
|
|
17
|
+
*
|
|
18
|
+
* Keep this file short and dumb. Rich per-library behaviour belongs in
|
|
19
|
+
* the author's actual `wyvrn.json` — the cookbook is just the "everyone
|
|
20
|
+
* hits these flags on day one" cheat sheet.
|
|
21
|
+
*
|
|
22
|
+
* @typedef {Object} CookbookEntry
|
|
23
|
+
* @property {'HeaderOnlyLib'|'StaticLib'|'DynamicLib'} [kind]
|
|
24
|
+
* Override `detect.js` when upstream's CMakeLists lies (e.g. fmt has
|
|
25
|
+
* both a STATIC lib and an INTERFACE `fmt-header-only`).
|
|
26
|
+
* @property {string[]} [configure]
|
|
27
|
+
* `-DKEY=VAL` args threaded into build.configure. Preserves order so a
|
|
28
|
+
* `-DBUILD_SHARED_LIBS=OFF` comes before a `-DXYZ_OPTION=...` override.
|
|
29
|
+
* @property {Record<string,string>} [dependencies]
|
|
30
|
+
* Known wyvrnpm deps — merged into manifest.dependencies. Versions
|
|
31
|
+
* use `"latest"` so the user picks up whatever the team's registry
|
|
32
|
+
* publishes; they can pin in review.
|
|
33
|
+
* @property {string[]} [notes]
|
|
34
|
+
* Human-readable reminders appended to the TODO report.
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
/** @type {Record<string, CookbookEntry>} */
|
|
38
|
+
const KNOWN_LIBRARIES = Object.freeze({
|
|
39
|
+
// ── Formatting / logging ─────────────────────────────────────────────
|
|
40
|
+
fmt: {
|
|
41
|
+
kind: 'StaticLib',
|
|
42
|
+
configure: ['-DFMT_TEST=OFF', '-DFMT_DOC=OFF'],
|
|
43
|
+
notes: [
|
|
44
|
+
'fmt also ships a `fmt-header-only` INTERFACE target. If you want ' +
|
|
45
|
+
'the header-only variant, declare kind=HeaderOnlyLib and add -DFMT_INSTALL=ON.',
|
|
46
|
+
],
|
|
47
|
+
},
|
|
48
|
+
spdlog: {
|
|
49
|
+
kind: 'StaticLib',
|
|
50
|
+
configure: [
|
|
51
|
+
'-DSPDLOG_BUILD_TESTS=OFF',
|
|
52
|
+
'-DSPDLOG_BUILD_EXAMPLE=OFF',
|
|
53
|
+
'-DSPDLOG_INSTALL=ON',
|
|
54
|
+
'-DSPDLOG_FMT_EXTERNAL=ON',
|
|
55
|
+
],
|
|
56
|
+
dependencies: { fmt: 'latest' },
|
|
57
|
+
notes: [
|
|
58
|
+
'SPDLOG_FMT_EXTERNAL=ON makes spdlog link against the wyvrnpm fmt package ' +
|
|
59
|
+
'instead of its bundled fork. Drop if you want the bundled copy.',
|
|
60
|
+
],
|
|
61
|
+
},
|
|
62
|
+
|
|
63
|
+
// ── JSON / config / serialization ────────────────────────────────────
|
|
64
|
+
json: { kind: 'HeaderOnlyLib', configure: ['-DJSON_BuildTests=OFF'] },
|
|
65
|
+
rapidjson: { kind: 'HeaderOnlyLib', configure: ['-DRAPIDJSON_BUILD_TESTS=OFF', '-DRAPIDJSON_BUILD_EXAMPLES=OFF', '-DRAPIDJSON_BUILD_DOC=OFF'] },
|
|
66
|
+
jsoncpp: { kind: 'StaticLib', configure: ['-DJSONCPP_WITH_TESTS=OFF', '-DJSONCPP_WITH_POST_BUILD_UNITTEST=OFF'] },
|
|
67
|
+
'yaml-cpp':{ kind: 'StaticLib', configure: ['-DYAML_CPP_BUILD_TESTS=OFF', '-DYAML_CPP_BUILD_TOOLS=OFF', '-DYAML_CPP_INSTALL=ON'] },
|
|
68
|
+
pugixml: { kind: 'StaticLib', configure: ['-DPUGIXML_BUILD_TESTS=OFF'] },
|
|
69
|
+
tinyxml2: { kind: 'StaticLib', configure: ['-Dtinyxml2_BUILD_TESTING=OFF'] },
|
|
70
|
+
cereal: { kind: 'HeaderOnlyLib', configure: ['-DJUST_INSTALL_CEREAL=ON'] },
|
|
71
|
+
'msgpack-c': { kind: 'StaticLib', configure: ['-DMSGPACK_BUILD_TESTS=OFF', '-DMSGPACK_BUILD_EXAMPLES=OFF'] },
|
|
72
|
+
|
|
73
|
+
// ── CLI / utilities ──────────────────────────────────────────────────
|
|
74
|
+
cli11: { kind: 'HeaderOnlyLib', configure: ['-DCLI11_BUILD_TESTS=OFF', '-DCLI11_BUILD_EXAMPLES=OFF'] },
|
|
75
|
+
cxxopts: { kind: 'HeaderOnlyLib', configure: ['-DCXXOPTS_BUILD_TESTS=OFF', '-DCXXOPTS_BUILD_EXAMPLES=OFF'] },
|
|
76
|
+
magic_enum: { kind: 'HeaderOnlyLib', configure: ['-DMAGIC_ENUM_OPT_BUILD_EXAMPLES=OFF', '-DMAGIC_ENUM_OPT_BUILD_TESTS=OFF'] },
|
|
77
|
+
date: { kind: 'StaticLib', configure: ['-DBUILD_TZ_LIB=ON', '-DUSE_SYSTEM_TZ_DB=OFF'] },
|
|
78
|
+
utfcpp: { kind: 'HeaderOnlyLib', configure: ['-DUTF8_TESTS=OFF', '-DUTF8_SAMPLES=OFF'] },
|
|
79
|
+
|
|
80
|
+
// ── Testing / benchmarking ──────────────────────────────────────────
|
|
81
|
+
catch2: { kind: 'StaticLib', configure: ['-DCATCH_INSTALL_DOCS=OFF', '-DCATCH_BUILD_TESTING=OFF'] },
|
|
82
|
+
doctest: { kind: 'HeaderOnlyLib', configure: ['-DDOCTEST_WITH_TESTS=OFF', '-DDOCTEST_WITH_MAIN_IN_STATIC_LIB=OFF'] },
|
|
83
|
+
benchmark: {
|
|
84
|
+
kind: 'StaticLib',
|
|
85
|
+
configure: ['-DBENCHMARK_ENABLE_TESTING=OFF', '-DBENCHMARK_ENABLE_GTEST_TESTS=OFF'],
|
|
86
|
+
notes: ['google/benchmark — only one of several projects named "benchmark"; confirm the repo URL.'],
|
|
87
|
+
},
|
|
88
|
+
|
|
89
|
+
// ── Compression ──────────────────────────────────────────────────────
|
|
90
|
+
zlib: {
|
|
91
|
+
kind: 'StaticLib',
|
|
92
|
+
configure: ['-DZLIB_BUILD_EXAMPLES=OFF'],
|
|
93
|
+
notes: [
|
|
94
|
+
'zlib is the textbook example for an `options.shared` toggle — see ' +
|
|
95
|
+
'references/worked-example-zlib.md. Consider declaring it before you publish.',
|
|
96
|
+
],
|
|
97
|
+
},
|
|
98
|
+
lz4: { kind: 'StaticLib', configure: ['-DLZ4_BUILD_LEGACY_LZ4C=OFF', '-DLZ4_BUILD_CLI=OFF', '-DBUILD_SHARED_LIBS=OFF'] },
|
|
99
|
+
snappy: { kind: 'StaticLib', configure: ['-DSNAPPY_BUILD_TESTS=OFF', '-DSNAPPY_BUILD_BENCHMARKS=OFF'] },
|
|
100
|
+
brotli: { kind: 'StaticLib', configure: ['-DBROTLI_DISABLE_TESTS=ON'] },
|
|
101
|
+
bzip2: {
|
|
102
|
+
notes: [
|
|
103
|
+
'bzip2 uses autotools (no CMakeLists.txt). Either ship a wrapper CMakeLists.txt ' +
|
|
104
|
+
'in your fork or prebuild + publish as a binary-only artefact.',
|
|
105
|
+
],
|
|
106
|
+
},
|
|
107
|
+
|
|
108
|
+
// ── Networking / HTTP ────────────────────────────────────────────────
|
|
109
|
+
'cpp-httplib': { kind: 'HeaderOnlyLib', configure: ['-DHTTPLIB_TEST=OFF'] },
|
|
110
|
+
cpr: {
|
|
111
|
+
kind: 'StaticLib',
|
|
112
|
+
configure: ['-DCPR_BUILD_TESTS=OFF', '-DCPR_USE_SYSTEM_CURL=ON'],
|
|
113
|
+
notes: ['cpr needs libcurl — add a wyvrnpm `libcurl` dep if your registry publishes one, or rely on system curl.'],
|
|
114
|
+
},
|
|
115
|
+
websocketpp: {
|
|
116
|
+
kind: 'HeaderOnlyLib',
|
|
117
|
+
notes: ['websocketpp requires boost::asio or standalone Asio — add the appropriate dep.'],
|
|
118
|
+
},
|
|
119
|
+
cppzmq: {
|
|
120
|
+
kind: 'HeaderOnlyLib',
|
|
121
|
+
notes: ['cppzmq needs libzmq — add a wyvrnpm dep for libzmq before publish.'],
|
|
122
|
+
},
|
|
123
|
+
hiredis: { kind: 'StaticLib', configure: ['-DDISABLE_TESTS=ON', '-DENABLE_EXAMPLES=OFF'] },
|
|
124
|
+
'redis-plus-plus': {
|
|
125
|
+
kind: 'StaticLib',
|
|
126
|
+
configure: ['-DREDIS_PLUS_PLUS_BUILD_TEST=OFF', '-DREDIS_PLUS_PLUS_USE_TLS=OFF'],
|
|
127
|
+
dependencies: { hiredis: 'latest' },
|
|
128
|
+
},
|
|
129
|
+
|
|
130
|
+
// ── Concurrency ──────────────────────────────────────────────────────
|
|
131
|
+
concurrentqueue: { kind: 'HeaderOnlyLib' },
|
|
132
|
+
readerwriterqueue: { kind: 'HeaderOnlyLib' },
|
|
133
|
+
|
|
134
|
+
// ── Graphics / image ─────────────────────────────────────────────────
|
|
135
|
+
stb: {
|
|
136
|
+
kind: 'HeaderOnlyLib',
|
|
137
|
+
notes: [
|
|
138
|
+
'stb is a header drop — no CMakeLists.txt upstream. Ship a small wrapper ' +
|
|
139
|
+
'CMakeLists.txt in your fork that declares an INTERFACE target with ' +
|
|
140
|
+
'target_include_directories(... INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) and install() rules.',
|
|
141
|
+
],
|
|
142
|
+
},
|
|
143
|
+
glm: { kind: 'HeaderOnlyLib', configure: ['-DGLM_TEST_ENABLE=OFF', '-DGLM_BUILD_LIBRARY=OFF'] },
|
|
144
|
+
imgui: {
|
|
145
|
+
notes: [
|
|
146
|
+
'imgui ships no CMakeLists.txt. Ship a wrapper CMakeLists.txt in your fork ' +
|
|
147
|
+
'that picks the backends you need (OpenGL3/Win32/DX11/etc) and declares a ' +
|
|
148
|
+
'StaticLib with them.',
|
|
149
|
+
],
|
|
150
|
+
},
|
|
151
|
+
nuklear: {
|
|
152
|
+
kind: 'HeaderOnlyLib',
|
|
153
|
+
notes: [
|
|
154
|
+
'Nuklear is a single-header drop. Same pattern as stb: ship an INTERFACE ' +
|
|
155
|
+
'wrapper CMakeLists.txt in your fork.',
|
|
156
|
+
],
|
|
157
|
+
},
|
|
158
|
+
|
|
159
|
+
// ── Database ─────────────────────────────────────────────────────────
|
|
160
|
+
sqlitecpp: { kind: 'StaticLib', configure: ['-DSQLITECPP_RUN_CPPLINT=OFF', '-DSQLITECPP_RUN_CPPCHECK=OFF', '-DSQLITECPP_BUILD_TESTS=OFF', '-DSQLITECPP_BUILD_EXAMPLES=OFF'] },
|
|
161
|
+
|
|
162
|
+
// ── Crypto ───────────────────────────────────────────────────────────
|
|
163
|
+
libsodium: {
|
|
164
|
+
notes: [
|
|
165
|
+
'libsodium uses autotools (configure.ac, Makefile.am). wyvrnpm source-build ' +
|
|
166
|
+
'supports cmake only — ship a wrapper CMakeLists.txt in your fork, or ' +
|
|
167
|
+
'prebuild + publish as a binary-only artefact.',
|
|
168
|
+
],
|
|
169
|
+
},
|
|
170
|
+
|
|
171
|
+
// ── Text / regex ─────────────────────────────────────────────────────
|
|
172
|
+
re2: { kind: 'StaticLib', configure: ['-DRE2_BUILD_TESTING=OFF'] },
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Look up cookbook hints for a given package tail (e.g. "fmt", "zlib").
|
|
177
|
+
* Case-insensitive; returns a defensive copy so callers can merge freely.
|
|
178
|
+
*
|
|
179
|
+
* @param {string} key
|
|
180
|
+
* @returns {CookbookEntry | null}
|
|
181
|
+
*/
|
|
182
|
+
function lookupCookbook(key) {
|
|
183
|
+
if (typeof key !== 'string') return null;
|
|
184
|
+
const normal = key.trim().toLowerCase();
|
|
185
|
+
if (!normal) return null;
|
|
186
|
+
const entry = KNOWN_LIBRARIES[normal];
|
|
187
|
+
if (!entry) return null;
|
|
188
|
+
return {
|
|
189
|
+
...entry,
|
|
190
|
+
configure: entry.configure ? [...entry.configure] : undefined,
|
|
191
|
+
dependencies: entry.dependencies ? { ...entry.dependencies } : undefined,
|
|
192
|
+
notes: entry.notes ? [...entry.notes] : undefined,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
module.exports = { KNOWN_LIBRARIES, lookupCookbook };
|