wyvrnpm 2.4.1 → 2.9.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 +414 -16
- package/bin/wyvrn.js +154 -11
- package/claude/skills/wyvrnpm.skill +0 -0
- package/cmake/variables.cmake +13 -3
- package/package.json +1 -1
- package/src/auth.js +66 -0
- package/src/build/cache.js +196 -0
- package/src/build/index.js +26 -4
- package/src/build/msvc-env.js +50 -7
- package/src/build/recipe.js +36 -3
- package/src/commands/add.js +2 -1
- package/src/commands/build.js +162 -36
- package/src/commands/cache.js +189 -0
- package/src/commands/configure.js +15 -4
- package/src/commands/init.js +36 -0
- package/src/commands/install-skill.js +8 -0
- package/src/commands/install.js +674 -400
- package/src/commands/link.js +320 -319
- package/src/commands/profile.js +237 -174
- package/src/commands/publish.js +435 -383
- package/src/commands/show.js +24 -9
- package/src/conf/index.js +391 -0
- package/src/conf/namespaces.js +94 -0
- package/src/context.js +230 -0
- package/src/download.js +135 -147
- package/src/http-fetch.js +53 -0
- package/src/logger.js +30 -2
- package/src/manifest.js +34 -7
- package/src/profile.js +148 -12
- package/src/providers/file.js +5 -19
- package/src/providers/http.js +26 -26
- package/src/providers/s3.js +29 -25
- package/src/resolve.js +47 -7
- package/src/settings-overrides.js +152 -0
- package/src/toolchain/presets.js +71 -31
- package/src/upload-built.js +11 -2
- package/src/zip-safe.js +52 -0
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ A simple, private C++ package manager that works with any static file hosting pr
|
|
|
4
4
|
|
|
5
5
|
There is no central registry. You control where packages are hosted.
|
|
6
6
|
|
|
7
|
-
> **README version: 2.
|
|
7
|
+
> **README version: 2.8.3** — Highlights since 2.4.0: non-ABI build-time `conf` block (CMake cache variables via recipe / team profile / `wyvrn.local.json` / CLI `--conf`), per-package `source` pin for multi-source defense, profile inheritance via `extends`, pattern-based `settingsOverrides` (`boost*: {...}`), `wyvrnpm cache list` / `cache prune` for selective source-build-cache cleanup, `install --dry-run` (JSON plan without side effects), `install --build=always` to force source-rebuild, `--token-env` for CI credentials, CloudFront/WAF-compatible HTTP provider (sends `User-Agent`, surfaces non-404 errors), publish preserves dependency ranges verbatim with lock snapshot moved to informational `publishedLock`, and a raft of security hardening (Zip Slip, MSVC arch allow-list). Full list in `claude/EVALUATION.md`.
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
|
@@ -97,6 +97,37 @@ wyvrnpm configure profile set-default release
|
|
|
97
97
|
|
|
98
98
|
Once a default profile is saved, `install` and `publish` use it automatically — no flags required.
|
|
99
99
|
|
|
100
|
+
### Profile inheritance — `extends` (2.8.0+)
|
|
101
|
+
|
|
102
|
+
Teams often end up with a small fleet of near-duplicate profiles (`windows-msvc-debug`, `windows-msvc-release`, `windows-msvc-x86`, …) that drift over time. A profile can inherit from another via `extends`:
|
|
103
|
+
|
|
104
|
+
```json
|
|
105
|
+
{
|
|
106
|
+
"extends": "windows-msvc-base",
|
|
107
|
+
"compiler.cppstd": "23"
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Or from multiple parents (later entries override earlier):
|
|
112
|
+
|
|
113
|
+
```json
|
|
114
|
+
{
|
|
115
|
+
"extends": ["windows-base", "team-defaults"],
|
|
116
|
+
"compiler.runtime": "static"
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Rules:
|
|
121
|
+
|
|
122
|
+
- `[settings]` fields merge per-key — child wins.
|
|
123
|
+
- The `conf` block (if present) merges per-leaf — child overrides single keys without dropping siblings.
|
|
124
|
+
- Overlay value `null` explicitly unsets a parent field (Conan's `None` semantics).
|
|
125
|
+
- Inheritance cycles are detected and fail with the full trail (`alpha → beta → alpha`).
|
|
126
|
+
- Missing parent names fail fast — no silent drop.
|
|
127
|
+
- `extends` itself is stripped from the resolved profile and is **not** folded into `profileHash`, so `{ "extends": "base" }` with no overrides hashes byte-identically to `base`.
|
|
128
|
+
|
|
129
|
+
`wyvrnpm configure profile show <name>` prints the raw `extends:` chain alongside the resolved `[settings]` so you can inspect inheritance without grepping JSON.
|
|
130
|
+
|
|
100
131
|
---
|
|
101
132
|
|
|
102
133
|
## Commands
|
|
@@ -161,7 +192,7 @@ Resolves the full dependency graph and downloads all packages.
|
|
|
161
192
|
3. **Source build** (with `--build=missing`) — clones the package's source at the published `gitSha`, resolves its own dependencies, invokes CMake through the shared toolchain generator, and caches the result under `%LOCALAPPDATA%\wyvrnpm\bc\`. On Windows/MSVC with a Ninja or Make generator, `vcvarsall.bat` is auto-activated.
|
|
162
193
|
4. **v1 legacy path** — only when no v2 entry exists for the package at all.
|
|
163
194
|
|
|
164
|
-
The pre-2.1 "same OS + arch, any compiler" loose fallback is
|
|
195
|
+
The pre-2.1 "same OS + arch, any compiler" loose fallback is no longer available. Publish a build for your profile, add a declarative `compatibility` block to the recipe, or rerun with `--build=missing` to source-build.
|
|
165
196
|
|
|
166
197
|
```bash
|
|
167
198
|
# Use configured sources and the default build profile
|
|
@@ -180,6 +211,13 @@ wyvrnpm install \
|
|
|
180
211
|
|
|
181
212
|
# Build any missing binary from source
|
|
182
213
|
wyvrnpm install --build=missing
|
|
214
|
+
|
|
215
|
+
# Force every dep to be rebuilt from source (debugging / reproducibility check)
|
|
216
|
+
wyvrnpm install --build=always
|
|
217
|
+
|
|
218
|
+
# Print the resolved install plan WITHOUT downloading (CI-friendly with --format=json)
|
|
219
|
+
wyvrnpm install --dry-run
|
|
220
|
+
wyvrnpm install --dry-run --format=json
|
|
183
221
|
```
|
|
184
222
|
|
|
185
223
|
**Options**
|
|
@@ -193,6 +231,8 @@ wyvrnpm install --build=missing
|
|
|
193
231
|
| `--timeout` | `300` | HTTP request timeout in seconds. |
|
|
194
232
|
| `--manifest` | `./wyvrn.json` | Path to the manifest file. |
|
|
195
233
|
| `--root` | `./` | Project root (packages extracted to `{root}/wyvrn_internal/`). |
|
|
234
|
+
| `--dry-run` | `false` | Run the resolver + profile/options math, print the install plan, and exit. No download, no `wyvrn.lock`, no `wyvrn_internal/`, no toolchain. Combine with `--format=json` for CI ingestion (payload carries `command: "install-dry-run"`). |
|
|
235
|
+
| `--conf` | — | Non-ABI build-time override. Repeatable. Format: `<namespace.leaf>=<value>` — e.g. `--conf cmake.cache.CHROMA_ENABLE_TEST=ON`. Layered: CLI > `wyvrn.local.json` > named-profile `conf` > recipe. Does **not** fold into `profileHash`. See [Build-time configuration (`conf`)](#build-time-configuration-conf). |
|
|
196
236
|
|
|
197
237
|
Packages are extracted to `wyvrn_internal/{name}/`. A `wyvrn.lock` file is written alongside the manifest recording the exact resolved versions, profile, and per-package SHA256. On subsequent installs the lock file pins all previously resolved versions — only newly added dependencies are resolved fresh.
|
|
198
238
|
|
|
@@ -215,6 +255,16 @@ After download, `install` also generates:
|
|
|
215
255
|
|
|
216
256
|
The optional helper `WYVRN_APPLY_ARCH_SUFFIX(<target> [BASE_NAME <name>])` from the bundled `macros.cmake` applies the suffix to a target's `OUTPUT_NAME` so x64 and x86 builds of the same library coexist on disk without overwriting each other. Target linkage (`target_link_libraries`) is unaffected — only the produced filename changes.
|
|
217
257
|
|
|
258
|
+
The bundled `variables.cmake` also suffixes the consumer's own output directories with `WYVRN_ARCH_SUFFIX` so multi-arch builds from one source tree don't clobber each other:
|
|
259
|
+
|
|
260
|
+
| Profile arch | Archive/library dir | Runtime (DLL/EXE) dir |
|
|
261
|
+
|---|---|---|
|
|
262
|
+
| `x86_64` / `armv8` | `output/lib64/` | `output/bin64/<CONFIG>/` |
|
|
263
|
+
| `x86` / `armv7` | `output/lib/` | `output/bin/<CONFIG>/` |
|
|
264
|
+
| unmapped | `output/lib/` | `output/bin/<CONFIG>/` |
|
|
265
|
+
|
|
266
|
+
Prior to `2.5.0` the runtime directory was always `output/bin/<CONFIG>/` regardless of arch — a multi-arch consumer building x64 then x86 would silently overwrite the first arch's DLLs. Scripts that hard-code `output/bin/…` expecting x64 payloads need to switch to `output/bin64/…` after upgrading.
|
|
267
|
+
|
|
218
268
|
```cmake
|
|
219
269
|
project(String CXX)
|
|
220
270
|
add_library(String STATIC ...)
|
|
@@ -235,6 +285,13 @@ wyvrnpm build
|
|
|
235
285
|
# Build Debug, verbose compiler output
|
|
236
286
|
wyvrnpm build --config Debug --verbose
|
|
237
287
|
|
|
288
|
+
# Build multiple configs in one go — configure runs once, build loops per config
|
|
289
|
+
wyvrnpm build --config Debug,Release --install
|
|
290
|
+
|
|
291
|
+
# Build every config the recipe declares (recipe's build.configs, or all four
|
|
292
|
+
# canonical configs if no recipe is present). Pairs naturally with --install.
|
|
293
|
+
wyvrnpm build --all-configs --install
|
|
294
|
+
|
|
238
295
|
# Use a specific profile's preset
|
|
239
296
|
wyvrnpm build --profile release
|
|
240
297
|
|
|
@@ -268,7 +325,8 @@ wyvrnpm build -- -j 8
|
|
|
268
325
|
|---|---|---|
|
|
269
326
|
| `--preset` / `-P` | `wyvrn-<profile>` | CMake configure preset name. |
|
|
270
327
|
| `--profile` / `-p` | *(config / "default")* | Build profile — determines the default preset name. |
|
|
271
|
-
| `--config` / `-c` | `Release` | Build configuration (`Debug` \| `Release` \| `RelWithDebInfo` \| `MinSizeRel`). |
|
|
328
|
+
| `--config` / `-c` | `Release` | Build configuration (`Debug` \| `Release` \| `RelWithDebInfo` \| `MinSizeRel`). Comma-separated to build multiple in one invocation (e.g. `Debug,Release`) — configure runs once, build (+ `--install`) loops per config. |
|
|
329
|
+
| `--all-configs` | `false` | Build every config from the recipe's `build.configs` (or all four canonical configs when no recipe is present). Takes precedence over `--config`. |
|
|
272
330
|
| `--target` / `-t` | *(all)* | Specific CMake target to build. |
|
|
273
331
|
| `--verbose` / `-v` | `false` | Pass `--verbose` to `cmake --build`. |
|
|
274
332
|
| `--clean` | `false` | Remove the build directory before configuring. |
|
|
@@ -303,7 +361,9 @@ wyvrnpm publish --source default
|
|
|
303
361
|
# Explicit destination URL
|
|
304
362
|
wyvrnpm publish --source s3://my-bucket/packages --aws-profile my-sso
|
|
305
363
|
|
|
306
|
-
# HTTP server with token auth
|
|
364
|
+
# HTTP server with token auth (CI-preferred: --token-env avoids argv leakage)
|
|
365
|
+
wyvrnpm publish --source https://pkg.corp.com --token-env WYVRN_HTTP_TOKEN
|
|
366
|
+
# Equivalent for interactive use; --token lands in shell history / ps output
|
|
307
367
|
wyvrnpm publish --source https://pkg.corp.com --token mytoken
|
|
308
368
|
|
|
309
369
|
# Local directory or SMB share
|
|
@@ -325,6 +385,7 @@ wyvrnpm publish --force
|
|
|
325
385
|
| `--profile` / `-p` | *(config / "default")* | Named build profile to publish under. |
|
|
326
386
|
| `--aws-profile` | *(config)* | AWS SSO profile for S3 authentication. |
|
|
327
387
|
| `--token` | *(config)* | Bearer token for HTTP server authentication. |
|
|
388
|
+
| `--token-env` | *(config)* | Name of an env var holding the bearer token. Preferred for CI — the literal value never lands in `argv` or shell history. |
|
|
328
389
|
| `--path` | `.` | Directory to zip and publish. |
|
|
329
390
|
| `--manifest` | `./wyvrn.json` | Path to the manifest file. |
|
|
330
391
|
| `--force` / `-f` | `false` | Overwrite an existing published version (same version + profile hash). |
|
|
@@ -370,6 +431,128 @@ wyvrnpm clean --build-cache
|
|
|
370
431
|
| Option | Default | Description |
|
|
371
432
|
|---|---|---|
|
|
372
433
|
| `--build-cache` | `false` | Also remove the source-build cache under `%LOCALAPPDATA%\wyvrnpm\bc\` (Unix: `~/.cache/wyvrnpm/bc/`). |
|
|
434
|
+
| `--uploaded-built` | `false` | Wipe only the local record of what this machine has uploaded via `--upload-built` (the `.uploaded-to.json` sidecars). Does **not** touch the registry, the artefacts, or `wyvrn_internal/`. |
|
|
435
|
+
|
|
436
|
+
For selective cache pruning (keep last N variants, drop entries older than N days), use `wyvrnpm cache prune` instead — see below.
|
|
437
|
+
|
|
438
|
+
---
|
|
439
|
+
|
|
440
|
+
### `wyvrnpm cache` (2.8.0+)
|
|
441
|
+
|
|
442
|
+
Inspect and selectively prune the machine-wide source-build cache at `%LOCALAPPDATA%\wyvrnpm\bc\` (Unix: `~/.cache/wyvrnpm/bc/`). Useful once `--upload-built` adoption balloons cache size on dev rigs — `clean --build-cache` is the blunt alternative that wipes everything.
|
|
443
|
+
|
|
444
|
+
```bash
|
|
445
|
+
# List every cached entry as a table
|
|
446
|
+
wyvrnpm cache list
|
|
447
|
+
|
|
448
|
+
# Filter by package name (glob)
|
|
449
|
+
wyvrnpm cache list "boost*"
|
|
450
|
+
|
|
451
|
+
# Machine-readable output for CI
|
|
452
|
+
wyvrnpm cache list --format json
|
|
453
|
+
|
|
454
|
+
# Keep the 2 most-recently-touched variants per (name, version)
|
|
455
|
+
wyvrnpm cache prune --keep-last 2
|
|
456
|
+
|
|
457
|
+
# Drop entries older than 30 days
|
|
458
|
+
wyvrnpm cache prune --older-than 30d
|
|
459
|
+
|
|
460
|
+
# Combine: keep 1 recent per version AND drop anything stale
|
|
461
|
+
wyvrnpm cache prune --keep-last 1 --older-than 30d
|
|
462
|
+
|
|
463
|
+
# Preview — print what would be removed, delete nothing
|
|
464
|
+
wyvrnpm cache prune --keep-last 2 --dry-run
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
**`cache list` options**
|
|
468
|
+
|
|
469
|
+
| Option | Default | Description |
|
|
470
|
+
|---|---|---|
|
|
471
|
+
| `[pattern]` / `--pattern` | *(none)* | Glob over package names (`*` for any chars, `?` for one). |
|
|
472
|
+
| `--format` | `text` | `text` (table) or `json` (structured payload for CI). |
|
|
473
|
+
|
|
474
|
+
**`cache prune` options**
|
|
475
|
+
|
|
476
|
+
| Option | Default | Description |
|
|
477
|
+
|---|---|---|
|
|
478
|
+
| `--keep-last <N>` | *(none)* | Retain the N most-recently-touched entries **per (name, version) group**. A four-profile rig keeping-last-2 still retains the two newest profile variants of each version. |
|
|
479
|
+
| `--older-than <dur>` | *(none)* | Remove entries whose mtime is older than the threshold. Format: `<number><unit>`, unit ∈ `s` / `m` / `h` / `d` (e.g. `30d`, `72h`). |
|
|
480
|
+
| `--pattern <glob>` | *(none)* | Restrict scope to package names matching the glob. |
|
|
481
|
+
| `--dry-run` | `false` | Print what would be removed without deleting. |
|
|
482
|
+
|
|
483
|
+
At least one of `--keep-last` / `--older-than` is required — calling `prune` bare errors out with a pointer to `clean --build-cache` (the nuke-everything path).
|
|
484
|
+
|
|
485
|
+
---
|
|
486
|
+
|
|
487
|
+
### `wyvrnpm show`
|
|
488
|
+
|
|
489
|
+
Read-only registry-metadata inspector. Given `<name>[@<version>[@<profileHash>]]`, queries the first configured install source that knows the package (override with `--source`) and prints what's published.
|
|
490
|
+
|
|
491
|
+
```bash
|
|
492
|
+
# Index of every published version (one HTTP round trip per source)
|
|
493
|
+
wyvrnpm show zlib
|
|
494
|
+
|
|
495
|
+
# Narrow to one version — fans out a per-profile query so uploadedBy,
|
|
496
|
+
# compatibility, and declared options show up per build
|
|
497
|
+
wyvrnpm show zlib@1.3.0.0
|
|
498
|
+
|
|
499
|
+
# Narrow to one specific build
|
|
500
|
+
wyvrnpm show zlib@1.3.0.0@a1b2c3d4e5f60718
|
|
501
|
+
|
|
502
|
+
# Pick the source explicitly (skips install-source lookup order)
|
|
503
|
+
wyvrnpm show zlib@1.3.0.0 --source s3://team-pkgs
|
|
504
|
+
|
|
505
|
+
# Machine-readable for CI ingestion
|
|
506
|
+
wyvrnpm show zlib@1.3.0.0 --format json
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
What gets surfaced per profile:
|
|
510
|
+
|
|
511
|
+
- **origin** — `author-publish` vs `consumer-upload` (derived from whether the manifest carries an `uploadedBy` block).
|
|
512
|
+
- **uploadedBy** — when set, the consumer-upload provenance (`kind`, `builtFromGit`, `builtFromSha`, `uploadedAt`, `wyvrnpmVersion`).
|
|
513
|
+
- **compatibility** — the recipe's declarative compat block, if any.
|
|
514
|
+
- **declaredOptions** — the author-declared `options` map from the recipe.
|
|
515
|
+
- **resolvedOptions** — the resolved option values that produced this profile's `profileHash`.
|
|
516
|
+
- **publishedConf** — recipe + CLI `--conf` the publisher captured (informational; doesn't affect resolution).
|
|
517
|
+
- **signature** — when PLAN-SIGNING phase 1 ships, signer identity; absent today.
|
|
518
|
+
|
|
519
|
+
Useful for: auditing consumer uploads (who pushed this artefact, from which commit), spotting profile drift between two consumers, verifying a package's declared options before adding it to a recipe.
|
|
520
|
+
|
|
521
|
+
**Options**
|
|
522
|
+
|
|
523
|
+
| Option | Default | Description |
|
|
524
|
+
|---|---|---|
|
|
525
|
+
| `pkg` *(positional)* | *(required)* | `<name>[@<version>[@<profileHash>]]` |
|
|
526
|
+
| `--source` / `-s` | *(first configured install source)* | URL or configured source name. Repeatable. |
|
|
527
|
+
| `--format` | `text` | `text` or `json` (see [Shape — `show`](#shape--show) below). |
|
|
528
|
+
| `--token` / `--token-env` / `--aws-profile` | | Auth forwarded to the provider the same way `install` does. |
|
|
529
|
+
|
|
530
|
+
---
|
|
531
|
+
|
|
532
|
+
### `wyvrnpm install-skill`
|
|
533
|
+
|
|
534
|
+
Installs the bundled wyvrnpm Agent Skill — the authoring guide Claude Code uses when it sees a `wyvrn.json` in the workspace. Ships as a `.skill` zip inside the npm package (`claude/skills/wyvrnpm.skill`) and is extracted into `~/.claude/skills/wyvrnpm/` on demand.
|
|
535
|
+
|
|
536
|
+
```bash
|
|
537
|
+
# One-shot: install the bundled skill for Claude Code
|
|
538
|
+
wyvrnpm install-skill --claude
|
|
539
|
+
|
|
540
|
+
# Overwrite an existing installation (e.g. after upgrading wyvrnpm)
|
|
541
|
+
wyvrnpm install-skill --claude --force
|
|
542
|
+
|
|
543
|
+
# Preview without writing
|
|
544
|
+
wyvrnpm install-skill --claude --dry-run
|
|
545
|
+
```
|
|
546
|
+
|
|
547
|
+
You only need this if you want Claude Code to pick up the skill. The CLI itself works without it.
|
|
548
|
+
|
|
549
|
+
**Options**
|
|
550
|
+
|
|
551
|
+
| Option | Default | Description |
|
|
552
|
+
|---|---|---|
|
|
553
|
+
| `--claude` | `false` | Install for Claude Code (extracts to `~/.claude/skills/wyvrnpm/` + writes the `.skill` zip alongside). Required — present so a future `--cursor` / `--vscode` target can slot in without CLI churn. |
|
|
554
|
+
| `--force` | `false` | Overwrite an existing skill install. Without it, the command refuses to clobber. |
|
|
555
|
+
| `--dry-run` | `false` | Print the destination paths and intended actions without writing. |
|
|
373
556
|
|
|
374
557
|
---
|
|
375
558
|
|
|
@@ -523,7 +706,8 @@ wyvrnpm configure add-source \
|
|
|
523
706
|
| `--name` | Yes | Unique name for this source. |
|
|
524
707
|
| `--url` | Yes | Destination URL, URI, or file path. |
|
|
525
708
|
| `--profile` | No | AWS SSO profile (S3 sources). |
|
|
526
|
-
| `--token` | No | Bearer token (HTTP sources). |
|
|
709
|
+
| `--token` | No | Bearer token (HTTP sources). Persisted in plaintext in `config.json` — prefer `--token-env` for CI and shared setups. |
|
|
710
|
+
| `--token-env` | No | Name of an env var whose value is the bearer token. Only the **name** lands in `config.json`; the value is resolved fresh on every `wyvrnpm` call. |
|
|
527
711
|
|
|
528
712
|
#### `wyvrnpm configure remove-source`
|
|
529
713
|
|
|
@@ -925,6 +1109,56 @@ Example:
|
|
|
925
1109
|
}
|
|
926
1110
|
```
|
|
927
1111
|
|
|
1112
|
+
### Per-dependency source pin (2.8.0+)
|
|
1113
|
+
|
|
1114
|
+
When you have more than one configured install source (e.g. a primary S3 bucket plus a mirror), you can pin a security-sensitive dep to its canonical source by name:
|
|
1115
|
+
|
|
1116
|
+
```json
|
|
1117
|
+
{
|
|
1118
|
+
"dependencies": {
|
|
1119
|
+
"OpenSSL": {
|
|
1120
|
+
"version": "3.0.0.0",
|
|
1121
|
+
"source": "primary-s3"
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
```
|
|
1126
|
+
|
|
1127
|
+
`"primary-s3"` must match a `name` from `wyvrnpm configure list`; an unknown name fails install with exit code 1 rather than silently fanning out. The pin closes two common multi-source holes:
|
|
1128
|
+
|
|
1129
|
+
- **Mirror shadowing.** A package accidentally published to the mirror can't substitute for the primary's copy.
|
|
1130
|
+
- **Dependency confusion.** A squatter on a secondary source can't poison the build.
|
|
1131
|
+
|
|
1132
|
+
Pins are direct-only — they don't cascade to the pinned package's own transitive deps. CLI `--source` overrides config entirely, so on a run with `--source`, any manifest pin is ignored with a warning rather than an error. The lockfile records `source: "<name>"` on pinned entries so reviewers can spot at a glance that the artefact came from the declared source; absent on non-pinned entries so pre-2.8.0 locks remain byte-identical.
|
|
1133
|
+
|
|
1134
|
+
### Pattern-based `settingsOverrides` (2.8.0+)
|
|
1135
|
+
|
|
1136
|
+
When many deps need the same settings override — every `boost-*` family member needing `compiler.cppstd: "17"`, or every `*-debug` variant needing `compiler.runtime: "static"` — declare the pattern at the top level of the manifest instead of copy-pasting per dep:
|
|
1137
|
+
|
|
1138
|
+
```json
|
|
1139
|
+
{
|
|
1140
|
+
"dependencies": {
|
|
1141
|
+
"boost-filesystem": "1.80.0.0",
|
|
1142
|
+
"boost-system": "1.80.0.0",
|
|
1143
|
+
"boost-thread": "1.80.0.0",
|
|
1144
|
+
"zlib": "1.3.0.0"
|
|
1145
|
+
},
|
|
1146
|
+
"settingsOverrides": {
|
|
1147
|
+
"boost*": { "compiler.cppstd": "17" },
|
|
1148
|
+
"*-debug": { "compiler.runtime": "static" }
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
```
|
|
1152
|
+
|
|
1153
|
+
Rules:
|
|
1154
|
+
|
|
1155
|
+
- Keys are globs — `*` matches any chars, `?` matches exactly one, literal names work too. Both ends are anchored (no substring match unless you add `*` on either side).
|
|
1156
|
+
- Values accept the same keys as profile overrides: `os`, `arch`, `compiler`, `compiler.version`, `compiler.cppstd`, `compiler.runtime`. Unknown keys fail install with a clear error.
|
|
1157
|
+
- More-specific patterns win: literal `"boost-filesystem"` beats `"boost*"`, which beats `"*"`.
|
|
1158
|
+
- A literal per-dep `settings` block inside `dependencies` still wins over any pattern. Use that for the one dep that deviates from the family rule.
|
|
1159
|
+
|
|
1160
|
+
Each matching pattern shifts that dep's `profileHash`, so different settings produce distinct registry artefacts — identical semantics to literal per-dep `settings`.
|
|
1161
|
+
|
|
928
1162
|
### Package options (`options`)
|
|
929
1163
|
|
|
930
1164
|
A library author can declare **options** — compile-time feature toggles that change the produced binary's ABI. Examples: `shared` (shared vs static library), `minizip` (zlib's minizip support), `fips` (OpenSSL's FIPS mode). Each option produces a distinct `profileHash`, so every option combination gets its own artefact on the registry.
|
|
@@ -1019,6 +1253,169 @@ On Windows with MSVC and a non-Visual-Studio generator (Ninja, Make), `vcvarsall
|
|
|
1019
1253
|
|
|
1020
1254
|
---
|
|
1021
1255
|
|
|
1256
|
+
## Build-time configuration (`conf`)
|
|
1257
|
+
|
|
1258
|
+
`conf` is wyvrnpm's channel for **non-ABI** build-time knobs — CMake cache variables, feature toggles that change `add_subdirectory()` but not the public binary, and (in future phases) other build-tool settings. It is a deliberate sibling of `options`, with the opposite hashing property:
|
|
1259
|
+
|
|
1260
|
+
| | `options` (F1) | `conf` (this section) |
|
|
1261
|
+
|---|---|---|
|
|
1262
|
+
| Folds into `profileHash`? | Yes — every combination is a distinct registry artefact. | **No.** Informational only; two builds with different `conf` still share the same `profileHash`. |
|
|
1263
|
+
| Typical use | `shared`/`minizip`/`fips` — things that genuinely change the binary. | `CHROMA_ENABLE_TEST`, `BUILD_DOCS`, `CMAKE_EXPORT_COMPILE_COMMANDS` — things that don't. |
|
|
1264
|
+
| Consumer can override? | Yes (per-dep `options` in `wyvrn.json` or `-o pkg:name=val` on CLI). | Yes (recipe → named-profile `conf` → `wyvrn.local.json` → `--conf`, in that precedence). |
|
|
1265
|
+
|
|
1266
|
+
Phase 1 (2.6.0+) supports a single namespace: `cmake.cache.<VAR>`. It flows into the generated `CMakePresets.json`'s `cacheVariables`.
|
|
1267
|
+
|
|
1268
|
+
### The four layers
|
|
1269
|
+
|
|
1270
|
+
```
|
|
1271
|
+
highest CLI --conf cmake.cache.X=ON
|
|
1272
|
+
│ ─────
|
|
1273
|
+
│ local wyvrn.local.json (per-developer, gitignored)
|
|
1274
|
+
│ ─────
|
|
1275
|
+
│ profile named-profile JSON.conf (team-shared, checked-in)
|
|
1276
|
+
│ ─────
|
|
1277
|
+
│ recipe wyvrn.json.conf (author defaults)
|
|
1278
|
+
▼ ─────
|
|
1279
|
+
lowest (nothing — key absent)
|
|
1280
|
+
```
|
|
1281
|
+
|
|
1282
|
+
**Per-leaf override, not per-branch replace.** A CLI `--conf cmake.cache.FOO=ON` on top of a recipe setting `BAR=OFF` yields both keys — it does not discard `BAR`. Any omitted layer is equivalent to an empty map at that position — a project with no `wyvrn.local.json` and no profile `conf` merges recipe + CLI exactly as phase 1.
|
|
1283
|
+
|
|
1284
|
+
### Recipe-level defaults
|
|
1285
|
+
|
|
1286
|
+
Authors can declare defaults on their package:
|
|
1287
|
+
|
|
1288
|
+
```json
|
|
1289
|
+
{
|
|
1290
|
+
"name": "ChromaSDK",
|
|
1291
|
+
"version": "2.5.0.0",
|
|
1292
|
+
"conf": {
|
|
1293
|
+
"cmake": {
|
|
1294
|
+
"cache": {
|
|
1295
|
+
"CHROMA_ENABLE_TEST": "OFF",
|
|
1296
|
+
"CHROMA_ENABLE_EXAMPLES": "OFF",
|
|
1297
|
+
"CHROMA_LOG_LEVEL": "WARNING"
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
```
|
|
1303
|
+
|
|
1304
|
+
`true`/`false` in the JSON are normalised to CMake `"ON"`/`"OFF"`; numbers are stringified; strings pass through.
|
|
1305
|
+
|
|
1306
|
+
### Per-developer overlay — `wyvrn.local.json`
|
|
1307
|
+
|
|
1308
|
+
Drop a `wyvrn.local.json` next to `wyvrn.json` for per-machine overrides. `wyvrnpm init` scaffolds a `.gitignore` entry for new projects; existing projects get a one-line nudge on `wyvrnpm install` when the file is present but not ignored.
|
|
1309
|
+
|
|
1310
|
+
```json
|
|
1311
|
+
{
|
|
1312
|
+
"conf": {
|
|
1313
|
+
"cmake": {
|
|
1314
|
+
"cache": {
|
|
1315
|
+
"CHROMA_ENABLE_TEST": "ON",
|
|
1316
|
+
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1321
|
+
```
|
|
1322
|
+
|
|
1323
|
+
Phase 1 accepts **only** the top-level key `conf` in this file — `dependencies` / `options` / anything else is a hard error, forecloseing the silent-inert footgun where a user writes `{ "dependencies": {...} }` expecting local dep overrides. Phase 2 will widen the allow-list.
|
|
1324
|
+
|
|
1325
|
+
### Team-shared overlay — named-profile `conf` (phase 2, 2.7.0+)
|
|
1326
|
+
|
|
1327
|
+
When every developer on a team would end up with the same `wyvrn.local.json`, check that shared policy into the named profile instead. A saved profile (e.g. `%LOCALAPPDATA%\wyvrnpm\profiles\team-default.json`) may carry an optional top-level `conf` block alongside its `[settings]`:
|
|
1328
|
+
|
|
1329
|
+
```json
|
|
1330
|
+
{
|
|
1331
|
+
"os": "Windows",
|
|
1332
|
+
"arch": "x86_64",
|
|
1333
|
+
"compiler": "msvc",
|
|
1334
|
+
"compiler.version": "193",
|
|
1335
|
+
"compiler.cppstd": "20",
|
|
1336
|
+
"compiler.runtime": "dynamic",
|
|
1337
|
+
"conf": {
|
|
1338
|
+
"cmake": {
|
|
1339
|
+
"cache": {
|
|
1340
|
+
"CHROMA_ENABLE_SANITIZERS": "OFF",
|
|
1341
|
+
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
|
|
1342
|
+
}
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
}
|
|
1346
|
+
```
|
|
1347
|
+
|
|
1348
|
+
Edit via the `configure profile set` convenience (repeatable, same `KEY=VAL` / bare-`KEY` / `KEY=` syntax as the other CLI sinks):
|
|
1349
|
+
|
|
1350
|
+
```bash
|
|
1351
|
+
wyvrnpm configure profile set --name team-default --conf cmake.cache.CMAKE_EXPORT_COMPILE_COMMANDS=ON
|
|
1352
|
+
wyvrnpm configure profile set --name team-default --conf cmake.cache.LEGACY_FLAG= # clears it
|
|
1353
|
+
```
|
|
1354
|
+
|
|
1355
|
+
Profile `conf` layers **between recipe and local**: a project's `wyvrn.local.json` (the individual override) still wins over team defaults, and CLI `--conf` still wins over everything. The distinction Conan makes between the `[conf]` block in a profile and the `-c` CLI flag maps directly onto this precedence.
|
|
1356
|
+
|
|
1357
|
+
Profile `conf` is **non-ABI**: adding or changing keys inside it does NOT shift `profileHash`, so switching a team policy between `ENABLE_SANITIZERS=ON` and `=OFF` does not invalidate already-downloaded artefacts. The invariant is locked in by `tests/profile-hash.test.js`.
|
|
1358
|
+
|
|
1359
|
+
Auto-detected profiles (when no on-disk profile file exists) never inject a `conf` layer — detection is about `[settings]` only.
|
|
1360
|
+
|
|
1361
|
+
### CLI — ad-hoc, one invocation
|
|
1362
|
+
|
|
1363
|
+
```bash
|
|
1364
|
+
# Single toggle
|
|
1365
|
+
wyvrnpm build --conf cmake.cache.CHROMA_ENABLE_TEST=ON
|
|
1366
|
+
|
|
1367
|
+
# Repeatable
|
|
1368
|
+
wyvrnpm build \
|
|
1369
|
+
--conf cmake.cache.CHROMA_ENABLE_TEST=ON \
|
|
1370
|
+
--conf cmake.cache.BUILD_DOCS=OFF
|
|
1371
|
+
|
|
1372
|
+
# Bare KEY is sugar for KEY=ON (CMake -D convention)
|
|
1373
|
+
wyvrnpm build --conf cmake.cache.CHROMA_ENABLE_TEST
|
|
1374
|
+
|
|
1375
|
+
# KEY= (empty RHS) clears a value inherited from a lower layer
|
|
1376
|
+
wyvrnpm build --conf cmake.cache.CHROMA_ENABLE_TEST=
|
|
1377
|
+
|
|
1378
|
+
# Also honoured on install and publish (publish records it as
|
|
1379
|
+
# `publishedConf` on the uploaded manifest — informational metadata
|
|
1380
|
+
# that `wyvrnpm show` surfaces).
|
|
1381
|
+
wyvrnpm install --conf cmake.cache.CHROMA_ENABLE_TEST=ON
|
|
1382
|
+
wyvrnpm publish --conf cmake.cache.BUILD_DOCS=OFF
|
|
1383
|
+
```
|
|
1384
|
+
|
|
1385
|
+
`--conf` on `wyvrnpm build` passes through to `cmake --preset` as `-D` / `-U` overrides **for that invocation only** — it does not regenerate `CMakePresets.json`. Persistent per-machine overrides belong in `wyvrn.local.json`; `wyvrnpm install` regenerates the preset deterministically with the overlay applied.
|
|
1386
|
+
|
|
1387
|
+
### Lockfile semantics
|
|
1388
|
+
|
|
1389
|
+
`wyvrn.lock` gains an informational `effectiveConf` block after each install:
|
|
1390
|
+
|
|
1391
|
+
```json
|
|
1392
|
+
{
|
|
1393
|
+
"wyvrnVersion": 2,
|
|
1394
|
+
"profileHash": "a1b2c3d4e5f60718",
|
|
1395
|
+
"effectiveConf": {
|
|
1396
|
+
"cmake": { "cache": { "CHROMA_ENABLE_TEST": "ON" } }
|
|
1397
|
+
},
|
|
1398
|
+
"packages": { ... }
|
|
1399
|
+
}
|
|
1400
|
+
```
|
|
1401
|
+
|
|
1402
|
+
This is diagnostic only — changing `conf` between installs shows up as a lockfile diff but never causes a relock or version change. Conf drift is a legitimate review signal, not an error.
|
|
1403
|
+
|
|
1404
|
+
### Source-build boundary
|
|
1405
|
+
|
|
1406
|
+
When `--build=missing` or `--build=always` source-builds a dependency, **only that dep's own recipe `conf`** flows into its CMake invocation. The root project's merged conf (including `wyvrn.local.json`, named-profile `conf`, and CLI `--conf`) never reaches a dep's source-build. This preserves cross-consumer reproducibility — two developers source-building the same `(name, version, profileHash)` produce the same binary regardless of their local overlays or team profile, which is load-bearing for `--upload-built`.
|
|
1407
|
+
|
|
1408
|
+
### Why this isn't `build.configure`
|
|
1409
|
+
|
|
1410
|
+
Existing authors using `build.configure: ["-DFOO=ON", "-DBAR=OFF"]` keep working unchanged. But `build.configure` has two weaknesses `conf` fixes:
|
|
1411
|
+
|
|
1412
|
+
1. **All-or-nothing.** A consumer can't disable one flag without overriding the whole array.
|
|
1413
|
+
2. **Opaque strings.** `"-DFOO=ON"` is parsed at configure time, not at manifest load.
|
|
1414
|
+
|
|
1415
|
+
Recipe authors writing new packages should prefer `conf.cmake.cache.FOO=ON` for cache variables and keep `build.configure` for non-cache args like `-G`, `-T`, or `-A`. Setting the same KEY in both `build.configure` (`-DKEY=...`) AND `conf.cmake.cache.KEY` is a recipe-normalise error — pick one route.
|
|
1416
|
+
|
|
1417
|
+
---
|
|
1418
|
+
|
|
1022
1419
|
## Compatibility Rules
|
|
1023
1420
|
|
|
1024
1421
|
Publishers declare an optional `compatibility` block in a package's `wyvrn.json`. It tells wyvrnpm which profile fields must match the consumer's profile exactly, and which may legitimately differ without breaking ABI. When no exact `profileHash` match exists on the registry, `install` evaluates this block against every published build for the requested `(name, version)` and picks the best compatible candidate.
|
|
@@ -1073,16 +1470,6 @@ When multiple published builds satisfy the consumer's profile, the winner is pic
|
|
|
1073
1470
|
|
|
1074
1471
|
The chosen candidate is logged along with a per-field summary (e.g. `compiler.cppstd 20→23 (lte), compiler.runtime=dynamic`).
|
|
1075
1472
|
|
|
1076
|
-
### Legacy loose fallback
|
|
1077
|
-
|
|
1078
|
-
The pre-2.1 "same OS + arch, any compiler" fallback is removed from the default resolution path. For one release cycle it remains reachable via an env var:
|
|
1079
|
-
|
|
1080
|
-
```bash
|
|
1081
|
-
WYVRNPM_ALLOW_LOOSE_COMPAT=1 wyvrnpm install
|
|
1082
|
-
```
|
|
1083
|
-
|
|
1084
|
-
This prints a deprecation warning every time it fires and will be removed in the next minor release. Prefer adding a real `compatibility` block to affected packages, or rebuilding with `--build=missing`.
|
|
1085
|
-
|
|
1086
1473
|
---
|
|
1087
1474
|
|
|
1088
1475
|
## Source Builds
|
|
@@ -1144,6 +1531,8 @@ Source builds are cached machine-wide, keyed by `(name, version, profileHash)`:
|
|
|
1144
1531
|
|
|
1145
1532
|
Re-running `install --build=missing` with the same inputs short-circuits to the cached artefact. The cache root is deliberately shallow (`bc/`, not `build-cache/`) to keep nested CMake paths under Windows' 260-char limit.
|
|
1146
1533
|
|
|
1534
|
+
`--build=always` (2.5.0+) ignores every registry-binary path — exact-match, compat-match, and any already-extracted `wyvrn_internal/{name}/` — and forces a source-build for every dep. Useful for debugging whether a registry binary differs from what the current source tree would produce, or for reproducibility verification. The build-cache short-circuit still applies: re-running `--build=always` with unchanged inputs completes in seconds.
|
|
1535
|
+
|
|
1147
1536
|
Clone behaviour is tri-tier:
|
|
1148
1537
|
|
|
1149
1538
|
1. **Shallow-SHA fetch** (`git fetch origin <sha> --depth=1`) — fastest; works when the git server allows it.
|
|
@@ -1193,7 +1582,7 @@ wyvrnpm install --build=missing --upload-built --upload-source team-s3
|
|
|
1193
1582
|
|
|
1194
1583
|
# Upload auth is resolved in order: CLI flag → named-source config → first configured publish source.
|
|
1195
1584
|
wyvrnpm install --build=missing --upload-built --aws-profile my-sso
|
|
1196
|
-
wyvrnpm install --build=missing --upload-built --token
|
|
1585
|
+
wyvrnpm install --build=missing --upload-built --token-env WYVRN_HTTP_TOKEN
|
|
1197
1586
|
```
|
|
1198
1587
|
|
|
1199
1588
|
Semantics:
|
|
@@ -1353,6 +1742,15 @@ wyvrnpm build --install --install-prefix C:\out\stage
|
|
|
1353
1742
|
|
|
1354
1743
|
# Install a specific config
|
|
1355
1744
|
wyvrnpm build --install --config Debug
|
|
1745
|
+
|
|
1746
|
+
# Install multiple configs in one invocation — configure runs once,
|
|
1747
|
+
# build + install loops per config. Before 2.9.0 this required two
|
|
1748
|
+
# separate `wyvrnpm build --install ...` invocations.
|
|
1749
|
+
wyvrnpm build --install --config Debug,Release
|
|
1750
|
+
|
|
1751
|
+
# Install every config declared in the recipe's build.configs
|
|
1752
|
+
# (or all four canonical configs when no recipe is present).
|
|
1753
|
+
wyvrnpm build --install --all-configs
|
|
1356
1754
|
```
|
|
1357
1755
|
|
|
1358
1756
|
### What it does, in order
|