putitoutthere 0.3.8 → 0.3.9

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.
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Every dependency entry declared by a parsed `Cargo.toml`, flattened
3
+ * across the tables cargo resolves. #621.
4
+ *
5
+ * Cargo accepts a dependency in more places than `[dependencies]`, and a
6
+ * stale version requirement in **any** of them fails resolution
7
+ * identically — verified against cargo 1.94.1 for `[dev-dependencies]`,
8
+ * `[build-dependencies]`, `[target.'cfg(…)'.dependencies]` and
9
+ * `[workspace.dependencies]`. A version rewrite that walks only
10
+ * `[dependencies]` therefore still leaves an unbuildable tree, so the
11
+ * flattening happens here, once, rather than at each call site.
12
+ *
13
+ * Pure: takes an already-parsed manifest, touches no I/O.
14
+ */
15
+ /** One dependency declaration, normalized to its object form. */
16
+ export interface CargoDepEntry {
17
+ /** The key as written — a rename, not necessarily the crate name. */
18
+ key: string;
19
+ /** `path = "…"` as written (relative to the manifest's directory). */
20
+ path?: string | undefined;
21
+ /** True when the entry carries a `version = "…"` requirement. */
22
+ hasVersionReq: boolean;
23
+ /** True when the entry defers to `[workspace.dependencies]`. */
24
+ inheritsFromWorkspace: boolean;
25
+ }
26
+ /**
27
+ * Flatten every dependency entry in `parsed`, including target-specific
28
+ * tables and `[workspace.dependencies]`.
29
+ *
30
+ * The shorthand form (`serde = "1"`) can never be a path dependency, so
31
+ * it is reported with no `path` rather than skipped — callers filter on
32
+ * `path` and would otherwise have to re-derive that fact.
33
+ */
34
+ export declare function cargoDepEntries(parsed: unknown): CargoDepEntry[];
35
+ //# sourceMappingURL=cargo-dep-entries.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cargo-dep-entries.d.ts","sourceRoot":"","sources":["../src/cargo-dep-entries.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,iEAAiE;AACjE,MAAM,WAAW,aAAa;IAC5B,qEAAqE;IACrE,GAAG,EAAE,MAAM,CAAC;IACZ,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,iEAAiE;IACjE,aAAa,EAAE,OAAO,CAAC;IACvB,gEAAgE;IAChE,qBAAqB,EAAE,OAAO,CAAC;CAChC;AAMD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,GAAG,aAAa,EAAE,CAahE"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Every dependency entry declared by a parsed `Cargo.toml`, flattened
3
+ * across the tables cargo resolves. #621.
4
+ *
5
+ * Cargo accepts a dependency in more places than `[dependencies]`, and a
6
+ * stale version requirement in **any** of them fails resolution
7
+ * identically — verified against cargo 1.94.1 for `[dev-dependencies]`,
8
+ * `[build-dependencies]`, `[target.'cfg(…)'.dependencies]` and
9
+ * `[workspace.dependencies]`. A version rewrite that walks only
10
+ * `[dependencies]` therefore still leaves an unbuildable tree, so the
11
+ * flattening happens here, once, rather than at each call site.
12
+ *
13
+ * Pure: takes an already-parsed manifest, touches no I/O.
14
+ */
15
+ /**
16
+ * Flatten every dependency entry in `parsed`, including target-specific
17
+ * tables and `[workspace.dependencies]`.
18
+ *
19
+ * The shorthand form (`serde = "1"`) can never be a path dependency, so
20
+ * it is reported with no `path` rather than skipped — callers filter on
21
+ * `path` and would otherwise have to re-derive that fact.
22
+ */
23
+ export function cargoDepEntries(parsed) {
24
+ // `?? {}` rather than a type guard: a primitive yields `undefined` for
25
+ // every lookup below, so only null/undefined need substituting, and the
26
+ // extra `typeof` arm a guard would carry could never change an outcome.
27
+ const root = (parsed ?? {});
28
+ const out = [];
29
+ for (const table of collectTables(root)) {
30
+ for (const [key, value] of Object.entries(table)) {
31
+ out.push(toEntry(key, value));
32
+ }
33
+ }
34
+ return out;
35
+ }
36
+ const DEP_TABLE_NAMES = ['dependencies', 'dev-dependencies', 'build-dependencies'];
37
+ /** Every dependency-bearing table: top level, per-target, and workspace. */
38
+ function collectTables(root) {
39
+ const tables = [];
40
+ const push = (v) => {
41
+ if (v !== null && typeof v === 'object') {
42
+ tables.push(v);
43
+ }
44
+ };
45
+ for (const name of DEP_TABLE_NAMES) {
46
+ push(root[name]);
47
+ }
48
+ // `[target.'cfg(unix)'.dependencies]` and friends. The cfg expression is
49
+ // an arbitrary string key, so every value under `target` is inspected.
50
+ const target = root['target'];
51
+ if (target !== null && typeof target === 'object') {
52
+ for (const perTarget of Object.values(target)) {
53
+ const tables_ = (perTarget ?? {});
54
+ for (const name of DEP_TABLE_NAMES) {
55
+ push(tables_[name]);
56
+ }
57
+ }
58
+ }
59
+ // `[workspace.dependencies]` — where an inheriting member's requirement
60
+ // actually lives, so the rewrite has to reach it.
61
+ const workspace = root['workspace'];
62
+ if (workspace !== null && typeof workspace === 'object') {
63
+ push(workspace['dependencies']);
64
+ }
65
+ return tables;
66
+ }
67
+ function toEntry(key, value) {
68
+ // `serde = "1"` — a bare version requirement; never a path dependency.
69
+ if (typeof value === 'string') {
70
+ return { key, hasVersionReq: true, inheritsFromWorkspace: false };
71
+ }
72
+ const obj = (value ?? {});
73
+ const path = typeof obj['path'] === 'string' ? obj['path'] : undefined;
74
+ return {
75
+ key,
76
+ path,
77
+ hasVersionReq: typeof obj['version'] === 'string',
78
+ inheritsFromWorkspace: obj['workspace'] === true,
79
+ };
80
+ }
81
+ //# sourceMappingURL=cargo-dep-entries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cargo-dep-entries.js","sourceRoot":"","sources":["../src/cargo-dep-entries.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAkBH;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAAC,MAAe;IAC7C,uEAAuE;IACvE,wEAAwE;IACxE,wEAAwE;IACxE,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,EAAE,CAA4B,CAAC;IACvD,MAAM,GAAG,GAAoB,EAAE,CAAC;IAEhC,KAAK,MAAM,KAAK,IAAI,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACjD,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,eAAe,GAAG,CAAC,cAAc,EAAE,kBAAkB,EAAE,oBAAoB,CAAU,CAAC;AAE5F,4EAA4E;AAC5E,SAAS,aAAa,CAAC,IAA6B;IAClD,MAAM,MAAM,GAAe,EAAE,CAAC;IAE9B,MAAM,IAAI,GAAG,CAAC,CAAU,EAAQ,EAAE;QAChC,IAAI,CAAC,KAAK,IAAI,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;YAAA,MAAM,CAAC,IAAI,CAAC,CAAa,CAAC,CAAC;QAAA,CAAC;IACxE,CAAC,CAAC;IAEF,KAAK,MAAM,IAAI,IAAI,eAAe,EAAE,CAAC;QAAA,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAAA,CAAC;IAEvD,yEAAyE;IACzE,uEAAuE;IACvE,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC9B,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAClD,KAAK,MAAM,SAAS,IAAI,MAAM,CAAC,MAAM,CAAC,MAAiC,CAAC,EAAE,CAAC;YACzE,MAAM,OAAO,GAAG,CAAC,SAAS,IAAI,EAAE,CAA4B,CAAC;YAC7D,KAAK,MAAM,IAAI,IAAI,eAAe,EAAE,CAAC;gBACnC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;YACtB,CAAC;QACH,CAAC;IACH,CAAC;IAED,wEAAwE;IACxE,kDAAkD;IAClD,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC;IACpC,IAAI,SAAS,KAAK,IAAI,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;QACxD,IAAI,CAAE,SAAqC,CAAC,cAAc,CAAC,CAAC,CAAC;IAC/D,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,OAAO,CAAC,GAAW,EAAE,KAAc;IAC1C,uEAAuE;IACvE,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,EAAE,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE,qBAAqB,EAAE,KAAK,EAAE,CAAC;IACpE,CAAC;IACD,MAAM,GAAG,GAAG,CAAC,KAAK,IAAI,EAAE,CAA4B,CAAC;IACrD,MAAM,IAAI,GAAG,OAAO,GAAG,CAAC,MAAM,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACvE,OAAO;QACL,GAAG;QACH,IAAI;QACJ,aAAa,EAAE,OAAO,GAAG,CAAC,SAAS,CAAC,KAAK,QAAQ;QACjD,qBAAqB,EAAE,GAAG,CAAC,WAAW,CAAC,KAAK,IAAI;KACjD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Rewrite the `version = "…"` requirement on a **path** dependency,
3
+ * preserving the rest of the manifest byte-for-byte. #621.
4
+ *
5
+ * Bumping an embedded crate without moving the requirements that point at
6
+ * it is worse than leaving it stale: cargo stops resolving entirely.
7
+ *
8
+ * error: failed to select a version for the requirement `demo-core = "^0.2"`
9
+ * candidate versions found which didn't match: 0.4.2
10
+ *
11
+ * That is a hard failure (exit 101) before anything compiles, and a
12
+ * `version` key alongside `path` is *mandatory* for any crate that also
13
+ * publishes to crates.io — so the shape that needs this is exactly the
14
+ * shape polyglot repos have.
15
+ *
16
+ * String surgery rather than a TOML round-trip, matching
17
+ * `replaceCargoVersion` and `replaceWorkspacePackageVersion`: re-emitting
18
+ * parsed TOML discards comments and formatting from a file the consumer
19
+ * owns.
20
+ *
21
+ * Only entries that also carry a `path` key are touched. A registry
22
+ * dependency that happens to share the key name keeps its requirement —
23
+ * rewriting pyo3's `0.22` to the release version would pin a version that
24
+ * does not exist.
25
+ */
26
+ /**
27
+ * Rewrite every `version` requirement declared for `depKey` **that also
28
+ * declares a `path`**, in either dependency-entry syntax:
29
+ *
30
+ * - inline table — `demo-core = { path = "../core", version = "0.2" }`
31
+ * - section table — `[dependencies.demo-core]` / `path` / `version`
32
+ *
33
+ * Both forms are scanned across the whole manifest, so a dependency
34
+ * declared in several tables (normal plus dev, plus a `cfg`-gated one)
35
+ * has every occurrence rewritten. Returns the source unchanged when the
36
+ * key declares no path-plus-version entry.
37
+ */
38
+ export declare function replaceDepVersionReq(source: string, depKey: string, version: string): string;
39
+ //# sourceMappingURL=replace-dep-version-req.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replace-dep-version-req.d.ts","sourceRoot":"","sources":["../src/replace-dep-version-req.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAOH;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAG5F"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Rewrite the `version = "…"` requirement on a **path** dependency,
3
+ * preserving the rest of the manifest byte-for-byte. #621.
4
+ *
5
+ * Bumping an embedded crate without moving the requirements that point at
6
+ * it is worse than leaving it stale: cargo stops resolving entirely.
7
+ *
8
+ * error: failed to select a version for the requirement `demo-core = "^0.2"`
9
+ * candidate versions found which didn't match: 0.4.2
10
+ *
11
+ * That is a hard failure (exit 101) before anything compiles, and a
12
+ * `version` key alongside `path` is *mandatory* for any crate that also
13
+ * publishes to crates.io — so the shape that needs this is exactly the
14
+ * shape polyglot repos have.
15
+ *
16
+ * String surgery rather than a TOML round-trip, matching
17
+ * `replaceCargoVersion` and `replaceWorkspacePackageVersion`: re-emitting
18
+ * parsed TOML discards comments and formatting from a file the consumer
19
+ * owns.
20
+ *
21
+ * Only entries that also carry a `path` key are touched. A registry
22
+ * dependency that happens to share the key name keeps its requirement —
23
+ * rewriting pyo3's `0.22` to the release version would pin a version that
24
+ * does not exist.
25
+ */
26
+ /** Escape a dependency key for literal use inside a RegExp. */
27
+ function escapeRe(s) {
28
+ return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
29
+ }
30
+ /**
31
+ * Rewrite every `version` requirement declared for `depKey` **that also
32
+ * declares a `path`**, in either dependency-entry syntax:
33
+ *
34
+ * - inline table — `demo-core = { path = "../core", version = "0.2" }`
35
+ * - section table — `[dependencies.demo-core]` / `path` / `version`
36
+ *
37
+ * Both forms are scanned across the whole manifest, so a dependency
38
+ * declared in several tables (normal plus dev, plus a `cfg`-gated one)
39
+ * has every occurrence rewritten. Returns the source unchanged when the
40
+ * key declares no path-plus-version entry.
41
+ */
42
+ export function replaceDepVersionReq(source, depKey, version) {
43
+ const key = escapeRe(depKey);
44
+ return replaceInlineTableForm(replaceSectionTableForm(source, key, version), key, version);
45
+ }
46
+ /**
47
+ * `[dependencies.demo-core]` … through to the next table header. Matches
48
+ * any dependency table — `[dev-dependencies.x]`,
49
+ * `[target.'cfg(unix)'.dependencies.x]` — via the `dependencies.` suffix
50
+ * on the header path. The body is consumed line by line, refusing any
51
+ * line that opens a new table, so a `[` inside a value (`features =
52
+ * ["cli"]`) cannot end the section early.
53
+ */
54
+ function replaceSectionTableForm(source, key, version) {
55
+ const section = new RegExp(`(^\\[[^\\]\\n]*dependencies\\.${key}\\][^\\n]*\\n)((?:(?!\\[)[^\\n]*(?:\\n|$))*)`, 'gm');
56
+ return source.replace(section, (whole, header, body) => body.includes('path') ? header + setVersionIn(body, version) : whole);
57
+ }
58
+ /**
59
+ * `demo-core = { path = "../core", version = "0.2" }`, including the
60
+ * multi-line brace form. Cargo dependency entries never nest a further
61
+ * `{ … }`, so the body is everything up to the first `}`.
62
+ */
63
+ function replaceInlineTableForm(source, key, version) {
64
+ const entry = new RegExp(`^[ \\t]*"?${key}"?[ \\t]*=[ \\t]*\\{[^}]*\\}`, 'gm');
65
+ return source.replace(entry, (whole) => whole.includes('path') ? setVersionIn(whole, version) : whole);
66
+ }
67
+ /**
68
+ * Replace the first `version = "…"` value in `segment`. Un-anchored so it
69
+ * covers both the one-line inline table and the multi-line/section forms
70
+ * where the key sits on its own line.
71
+ */
72
+ function setVersionIn(segment, version) {
73
+ return segment.replace(/(\bversion[ \t]*=[ \t]*")([^"]*)(")/, `$1${version}$3`);
74
+ }
75
+ //# sourceMappingURL=replace-dep-version-req.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replace-dep-version-req.js","sourceRoot":"","sources":["../src/replace-dep-version-req.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,+DAA+D;AAC/D,SAAS,QAAQ,CAAC,CAAS;IACzB,OAAO,CAAC,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AAClD,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAc,EAAE,MAAc,EAAE,OAAe;IAClF,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC7B,OAAO,sBAAsB,CAAC,uBAAuB,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;AAC7F,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,uBAAuB,CAAC,MAAc,EAAE,GAAW,EAAE,OAAe;IAC3E,MAAM,OAAO,GAAG,IAAI,MAAM,CACxB,iCAAiC,GAAG,8CAA8C,EAClF,IAAI,CACL,CAAC;IACF,OAAO,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAc,EAAE,IAAY,EAAE,EAAE,CACrE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CACrE,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,sBAAsB,CAAC,MAAc,EAAE,GAAW,EAAE,OAAe;IAC1E,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,aAAa,GAAG,8BAA8B,EAAE,IAAI,CAAC,CAAC;IAC/E,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,KAAa,EAAE,EAAE,CAC7C,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAC9D,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,YAAY,CAAC,OAAe,EAAE,OAAe;IACpD,OAAO,OAAO,CAAC,OAAO,CAAC,qCAAqC,EAAE,KAAK,OAAO,IAAI,CAAC,CAAC;AAClF,CAAC"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Resolve a manifest's dependency entries to the on-disk directories they
3
+ * point at. #621.
4
+ *
5
+ * Two indirections have to be followed before a `path` is in hand, and
6
+ * missing either one silently drops a crate from the version rewrite:
7
+ *
8
+ * - a member may defer to the workspace (`demo-core.workspace = true`),
9
+ * which puts both the `path` and the version requirement in the
10
+ * workspace root's `[workspace.dependencies]`, a different file;
11
+ * - `path` is relative to the *declaring manifest's* directory, and for
12
+ * an inherited entry that is the workspace root, not the member.
13
+ *
14
+ * Shared by the discovery walk and the requirement rewrite so the two can
15
+ * never disagree about which crates are in scope.
16
+ */
17
+ /** A dependency entry that resolves to a directory on disk. */
18
+ export interface ResolvedDepDir {
19
+ /** The dependency key as written in the manifest being rewritten. */
20
+ key: string;
21
+ /** Absolute directory of the dependency crate. */
22
+ dir: string;
23
+ /** True when the entry carries a `version = "…"` requirement. */
24
+ hasVersionReq: boolean;
25
+ /**
26
+ * True when the requirement lives in the workspace root rather than in
27
+ * this manifest — the rewrite has to target the root's file instead.
28
+ */
29
+ inheritsFromWorkspace: boolean;
30
+ }
31
+ /**
32
+ * Every path dependency declared by `parsed`, resolved to an absolute
33
+ * directory. Registry dependencies are omitted — they have no directory
34
+ * and must never be rewritten.
35
+ *
36
+ * `workspaceParsed` is the parsed workspace-root manifest (or `null` when
37
+ * there is no workspace); it supplies `[workspace.dependencies]` for
38
+ * inheriting entries.
39
+ */
40
+ export declare function resolveDepDirs(parsed: unknown, manifestDir: string, workspaceParsed: unknown, workspaceRoot: string | null): ResolvedDepDir[];
41
+ //# sourceMappingURL=resolve-dep-dirs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-dep-dirs.d.ts","sourceRoot":"","sources":["../src/resolve-dep-dirs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,+DAA+D;AAC/D,MAAM,WAAW,cAAc;IAC7B,qEAAqE;IACrE,GAAG,EAAE,MAAM,CAAC;IACZ,kDAAkD;IAClD,GAAG,EAAE,MAAM,CAAC;IACZ,iEAAiE;IACjE,aAAa,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,qBAAqB,EAAE,OAAO,CAAC;CAChC;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,OAAO,EACf,WAAW,EAAE,MAAM,EACnB,eAAe,EAAE,OAAO,EACxB,aAAa,EAAE,MAAM,GAAG,IAAI,GAC3B,cAAc,EAAE,CA+BlB"}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Resolve a manifest's dependency entries to the on-disk directories they
3
+ * point at. #621.
4
+ *
5
+ * Two indirections have to be followed before a `path` is in hand, and
6
+ * missing either one silently drops a crate from the version rewrite:
7
+ *
8
+ * - a member may defer to the workspace (`demo-core.workspace = true`),
9
+ * which puts both the `path` and the version requirement in the
10
+ * workspace root's `[workspace.dependencies]`, a different file;
11
+ * - `path` is relative to the *declaring manifest's* directory, and for
12
+ * an inherited entry that is the workspace root, not the member.
13
+ *
14
+ * Shared by the discovery walk and the requirement rewrite so the two can
15
+ * never disagree about which crates are in scope.
16
+ */
17
+ import { isAbsolute, resolve } from 'node:path';
18
+ import { cargoDepEntries } from './cargo-dep-entries.js';
19
+ /**
20
+ * Every path dependency declared by `parsed`, resolved to an absolute
21
+ * directory. Registry dependencies are omitted — they have no directory
22
+ * and must never be rewritten.
23
+ *
24
+ * `workspaceParsed` is the parsed workspace-root manifest (or `null` when
25
+ * there is no workspace); it supplies `[workspace.dependencies]` for
26
+ * inheriting entries.
27
+ */
28
+ export function resolveDepDirs(parsed, manifestDir, workspaceParsed, workspaceRoot) {
29
+ // Only consult the workspace table when there is a root to resolve its
30
+ // relative paths against; an empty map then makes every inherited lookup
31
+ // miss, so no separate null check is needed per entry.
32
+ const inherited = workspaceRoot === null
33
+ ? new Map()
34
+ : workspaceDepDirs(workspaceParsed, workspaceRoot);
35
+ const out = [];
36
+ for (const entry of cargoDepEntries(parsed)) {
37
+ if (entry.path !== undefined) {
38
+ out.push({
39
+ key: entry.key,
40
+ dir: absolute(entry.path, manifestDir),
41
+ hasVersionReq: entry.hasVersionReq,
42
+ inheritsFromWorkspace: false,
43
+ });
44
+ continue;
45
+ }
46
+ if (!entry.inheritsFromWorkspace) {
47
+ continue;
48
+ }
49
+ const ws = inherited.get(entry.key);
50
+ if (ws === undefined) {
51
+ continue;
52
+ }
53
+ out.push({
54
+ key: entry.key,
55
+ dir: ws.dir,
56
+ hasVersionReq: ws.hasVersionReq,
57
+ inheritsFromWorkspace: true,
58
+ });
59
+ }
60
+ return out;
61
+ }
62
+ /**
63
+ * `[workspace.dependencies]` entries that carry a `path`, keyed by name and
64
+ * already resolved against `workspaceRoot` — the manifest that declared
65
+ * them, and therefore the base those relative paths are written against.
66
+ */
67
+ function workspaceDepDirs(workspaceParsed, workspaceRoot) {
68
+ const map = new Map();
69
+ // Optional chaining rather than a guard per level: a primitive yields
70
+ // `undefined` for the next lookup anyway, so only null/undefined need
71
+ // handling and each `typeof` arm would be unobservable.
72
+ const workspace = workspaceParsed?.workspace;
73
+ const deps = workspace?.dependencies;
74
+ for (const [key, value] of Object.entries((deps ?? {}))) {
75
+ const obj = (value ?? {});
76
+ if (typeof obj['path'] !== 'string') {
77
+ continue;
78
+ }
79
+ map.set(key, {
80
+ dir: absolute(obj['path'], workspaceRoot),
81
+ hasVersionReq: typeof obj['version'] === 'string',
82
+ });
83
+ }
84
+ return map;
85
+ }
86
+ function absolute(p, base) {
87
+ return isAbsolute(p) ? p : resolve(base, p);
88
+ }
89
+ //# sourceMappingURL=resolve-dep-dirs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-dep-dirs.js","sourceRoot":"","sources":["../src/resolve-dep-dirs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEhD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAiBzD;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAC5B,MAAe,EACf,WAAmB,EACnB,eAAwB,EACxB,aAA4B;IAE5B,uEAAuE;IACvE,yEAAyE;IACzE,uDAAuD;IACvD,MAAM,SAAS,GACb,aAAa,KAAK,IAAI;QACpB,CAAC,CAAC,IAAI,GAAG,EAAmD;QAC5D,CAAC,CAAC,gBAAgB,CAAC,eAAe,EAAE,aAAa,CAAC,CAAC;IACvD,MAAM,GAAG,GAAqB,EAAE,CAAC;IAEjC,KAAK,MAAM,KAAK,IAAI,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5C,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC7B,GAAG,CAAC,IAAI,CAAC;gBACP,GAAG,EAAE,KAAK,CAAC,GAAG;gBACd,GAAG,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,WAAW,CAAC;gBACtC,aAAa,EAAE,KAAK,CAAC,aAAa;gBAClC,qBAAqB,EAAE,KAAK;aAC7B,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,qBAAqB,EAAE,CAAC;YAAA,SAAS;QAAA,CAAC;QAC7C,MAAM,EAAE,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;YAAA,SAAS;QAAA,CAAC;QACjC,GAAG,CAAC,IAAI,CAAC;YACP,GAAG,EAAE,KAAK,CAAC,GAAG;YACd,GAAG,EAAE,EAAE,CAAC,GAAG;YACX,aAAa,EAAE,EAAE,CAAC,aAAa;YAC/B,qBAAqB,EAAE,IAAI;SAC5B,CAAC,CAAC;IACL,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,SAAS,gBAAgB,CACvB,eAAwB,EACxB,aAAqB;IAErB,MAAM,GAAG,GAAG,IAAI,GAAG,EAAmD,CAAC;IACvE,sEAAsE;IACtE,sEAAsE;IACtE,wDAAwD;IACxD,MAAM,SAAS,GAAI,eAAkD,EAAE,SAAS,CAAC;IACjF,MAAM,IAAI,GAAI,SAA+C,EAAE,YAAY,CAAC;IAE5E,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,IAAI,EAAE,CAA4B,CAAC,EAAE,CAAC;QACnF,MAAM,GAAG,GAAG,CAAC,KAAK,IAAI,EAAE,CAA4B,CAAC;QACrD,IAAI,OAAO,GAAG,CAAC,MAAM,CAAC,KAAK,QAAQ,EAAE,CAAC;YAAA,SAAS;QAAA,CAAC;QAChD,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE;YACX,GAAG,EAAE,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC;YACzC,aAAa,EAAE,OAAO,GAAG,CAAC,SAAS,CAAC,KAAK,QAAQ;SAClD,CAAC,CAAC;IACL,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,QAAQ,CAAC,CAAS,EAAE,IAAY;IACvC,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;AAC9C,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"write-crate-version.d.ts","sourceRoot":"","sources":["../src/write-crate-version.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAOH;;;;;;;;;;GAUG;AACH,wBAAsB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAepG"}
1
+ {"version":3,"file":"write-crate-version.d.ts","sourceRoot":"","sources":["../src/write-crate-version.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAQH;;;;;;;;;;GAUG;AACH,wBAAsB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAoBpG"}
@@ -19,6 +19,7 @@
19
19
  */
20
20
  import { readFile } from 'node:fs/promises';
21
21
  import { join } from 'node:path';
22
+ import { writeEmbeddedCrateVersions } from './write-embedded-crate-versions.js';
22
23
  import { writeResolvedCargoVersion } from './write-resolved-cargo-version.js';
23
24
  /**
24
25
  * Rewrite `[package].version` in the crate at `crateDir` to `version`
@@ -43,6 +44,11 @@ export async function writeCrateVersionForBuild(crateDir, version) {
43
44
  }
44
45
  throw err;
45
46
  }
46
- return await writeResolvedCargoVersion(crateDir, original, version);
47
+ const written = await writeResolvedCargoVersion(crateDir, original, version);
48
+ // #621: the compiled binary also embeds every in-repo crate this one
49
+ // pulls in by path, and it is often the *dependency* that owns the
50
+ // version-bearing symbol. Bumping only this crate ships a stale literal.
51
+ const embedded = await writeEmbeddedCrateVersions(crateDir, version);
52
+ return [...new Set([...written, ...embedded])];
47
53
  }
48
54
  //# sourceMappingURL=write-crate-version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"write-crate-version.js","sourceRoot":"","sources":["../src/write-crate-version.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAE9E;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAC,QAAgB,EAAE,OAAe;IAC/E,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IAC/C,IAAI,QAAgB,CAAC;IACrB,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAC/C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACrD,MAAM,IAAI,KAAK,CACb,gDAAgD,SAAS,wGAAwG,EACjK,EAAE,KAAK,EAAE,GAAG,EAAE,CACf,CAAC;QACJ,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;IACD,OAAO,MAAM,yBAAyB,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;AACtE,CAAC"}
1
+ {"version":3,"file":"write-crate-version.js","sourceRoot":"","sources":["../src/write-crate-version.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AAChF,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAE9E;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAC,QAAgB,EAAE,OAAe;IAC/E,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IAC/C,IAAI,QAAgB,CAAC;IACrB,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAC/C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACrD,MAAM,IAAI,KAAK,CACb,gDAAgD,SAAS,wGAAwG,EACjK,EAAE,KAAK,EAAE,GAAG,EAAE,CACf,CAAC;QACJ,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,yBAAyB,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC7E,qEAAqE;IACrE,mEAAmE;IACnE,yEAAyE;IACzE,MAAM,QAAQ,GAAG,MAAM,0BAA0B,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACrE,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;AACjD,CAAC"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Bump every in-repo crate an artifact compiles, plus the version
3
+ * requirements that point at them. #621.
4
+ *
5
+ * The three pre-build writers each bump the crate the build tool reads as
6
+ * its version source — maturin's `matrix.path`, `bundle_cli.crate_path`,
7
+ * the napi crate. That answers "what version is this artifact?" but not
8
+ * "whose `CARGO_PKG_VERSION` is observable *from* this artifact?" Those
9
+ * sets coincide only when the artifact is one crate deep. Embed a sibling
10
+ * by path, let the sibling own the version-bearing symbol (clap's
11
+ * `#[command(version)]` expands `env!("CARGO_PKG_VERSION")` inside the
12
+ * crate where the attribute is written), and nothing bumps the sibling.
13
+ *
14
+ * `CARGO_PKG_VERSION` is a compile-time constant scoped per crate and has
15
+ * no env override — not `CARGO_PKG_VERSION=… cargo build`, not
16
+ * `.cargo/config.toml [env]` with `force = true`. Rewriting the manifest
17
+ * before the build is the only lever there is.
18
+ *
19
+ * **Semantics: the artifact's version wins.** Every in-repo crate the
20
+ * artifact compiles is stamped with the artifact's release version, so a
21
+ * user who installs `dirsql 0.4.2` sees `0.4.2` from every surface the
22
+ * artifact exposes. The alternative — giving each declared `[[package]]`
23
+ * its own planned version — is indistinguishable for a repo whose crates
24
+ * cascade together at one version, and differs only where a repo keeps
25
+ * crates on deliberately separate version lines. It can be layered on
26
+ * later using this same requirement-rewrite machinery.
27
+ *
28
+ * The rewrites are ephemeral: the build job's checkout is thrown away and
29
+ * `publish` runs in a separate job off a fresh checkout, so nothing here
30
+ * reaches the crates handler's dirty-tree check or a published manifest.
31
+ */
32
+ /**
33
+ * Walk the path-dependency graph out of `startDir`, bump every crate
34
+ * reached to `version`, and rewrite every in-repo version requirement
35
+ * that points at one of them. Returns the absolute paths modified.
36
+ *
37
+ * `startDir` itself is assumed already bumped by the caller (that is the
38
+ * pre-existing writer's job); it is still included when rewriting
39
+ * requirements, since a sibling may depend on it.
40
+ *
41
+ * Reachability from the built crate is the criterion, not workspace
42
+ * membership: a sibling member nobody depends on is not in the artifact
43
+ * and is left alone.
44
+ */
45
+ export declare function writeEmbeddedCrateVersions(startDir: string, version: string): Promise<string[]>;
46
+ //# sourceMappingURL=write-embedded-crate-versions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write-embedded-crate-versions.d.ts","sourceRoot":"","sources":["../src/write-embedded-crate-versions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAkBH;;;;;;;;;;;;GAYG;AACH,wBAAsB,0BAA0B,CAC9C,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,EAAE,CAAC,CA0DnB"}
@@ -0,0 +1,172 @@
1
+ /**
2
+ * Bump every in-repo crate an artifact compiles, plus the version
3
+ * requirements that point at them. #621.
4
+ *
5
+ * The three pre-build writers each bump the crate the build tool reads as
6
+ * its version source — maturin's `matrix.path`, `bundle_cli.crate_path`,
7
+ * the napi crate. That answers "what version is this artifact?" but not
8
+ * "whose `CARGO_PKG_VERSION` is observable *from* this artifact?" Those
9
+ * sets coincide only when the artifact is one crate deep. Embed a sibling
10
+ * by path, let the sibling own the version-bearing symbol (clap's
11
+ * `#[command(version)]` expands `env!("CARGO_PKG_VERSION")` inside the
12
+ * crate where the attribute is written), and nothing bumps the sibling.
13
+ *
14
+ * `CARGO_PKG_VERSION` is a compile-time constant scoped per crate and has
15
+ * no env override — not `CARGO_PKG_VERSION=… cargo build`, not
16
+ * `.cargo/config.toml [env]` with `force = true`. Rewriting the manifest
17
+ * before the build is the only lever there is.
18
+ *
19
+ * **Semantics: the artifact's version wins.** Every in-repo crate the
20
+ * artifact compiles is stamped with the artifact's release version, so a
21
+ * user who installs `dirsql 0.4.2` sees `0.4.2` from every surface the
22
+ * artifact exposes. The alternative — giving each declared `[[package]]`
23
+ * its own planned version — is indistinguishable for a repo whose crates
24
+ * cascade together at one version, and differs only where a repo keeps
25
+ * crates on deliberately separate version lines. It can be layered on
26
+ * later using this same requirement-rewrite machinery.
27
+ *
28
+ * The rewrites are ephemeral: the build job's checkout is thrown away and
29
+ * `publish` runs in a separate job off a fresh checkout, so nothing here
30
+ * reaches the crates handler's dirty-tree check or a published manifest.
31
+ */
32
+ import { readFile, writeFile } from 'node:fs/promises';
33
+ import { join, resolve } from 'node:path';
34
+ import { parse as parseToml } from 'smol-toml';
35
+ import { findWorkspaceRoot } from './find-workspace-root.js';
36
+ import { replaceDepVersionReq } from './replace-dep-version-req.js';
37
+ import { resolveDepDirs } from './resolve-dep-dirs.js';
38
+ import { writeResolvedCargoVersion } from './write-resolved-cargo-version.js';
39
+ /**
40
+ * Walk the path-dependency graph out of `startDir`, bump every crate
41
+ * reached to `version`, and rewrite every in-repo version requirement
42
+ * that points at one of them. Returns the absolute paths modified.
43
+ *
44
+ * `startDir` itself is assumed already bumped by the caller (that is the
45
+ * pre-existing writer's job); it is still included when rewriting
46
+ * requirements, since a sibling may depend on it.
47
+ *
48
+ * Reachability from the built crate is the criterion, not workspace
49
+ * membership: a sibling member nobody depends on is not in the artifact
50
+ * and is left alone.
51
+ */
52
+ export async function writeEmbeddedCrateVersions(startDir, version) {
53
+ // Canonicalize before anything is compared. Every directory discovered
54
+ // below arrives via `resolve`, so a caller-supplied `startDir` that is
55
+ // relative, trailing-separated, or (on Windows) drive-letter-less would
56
+ // never equal its own resolved form — and the identity checks that keep
57
+ // the walk finite and stop the starting crate being re-bumped are all
58
+ // string equality on these paths.
59
+ const start = resolve(startDir);
60
+ // Any non-string stands for "no workspace above this crate" — the walk
61
+ // legitimately returns null at the filesystem root.
62
+ const found = await findWorkspaceRoot(start);
63
+ const workspaceRoot = typeof found === 'string' ? found : null;
64
+ const workspaceParsed = workspaceRoot === null ? null : (await readManifest(workspaceRoot))?.parsed;
65
+ const embedded = await collectEmbedded(start, workspaceParsed, workspaceRoot);
66
+ const written = new Set();
67
+ // 1. Bump each embedded crate. `writeResolvedCargoVersion` follows
68
+ // `version.workspace = true` up to the workspace root (#428).
69
+ for (const dir of embedded) {
70
+ const manifest = await readManifest(dir);
71
+ // A virtual manifest declares `[workspace]` but no crate to version.
72
+ if (manifest === null || !hasPackageTable(manifest.parsed)) {
73
+ continue;
74
+ }
75
+ for (const p of await writeResolvedCargoVersion(dir, manifest.source, version)) {
76
+ written.add(p);
77
+ }
78
+ }
79
+ // 2. Rewrite requirements pointing at anything bumped. The workspace
80
+ // root is included because an inheriting member's requirement lives
81
+ // there, in a file no member's own rewrite would touch.
82
+ const bumped = new Set([...embedded, start]);
83
+ const manifestDirs = new Set([...embedded, start]);
84
+ if (workspaceRoot !== null) {
85
+ manifestDirs.add(workspaceRoot);
86
+ }
87
+ for (const dir of manifestDirs) {
88
+ const manifest = await readManifest(dir);
89
+ if (manifest === null) {
90
+ continue;
91
+ }
92
+ let updated = manifest.source;
93
+ for (const dep of resolveDepDirs(manifest.parsed, dir, workspaceParsed, workspaceRoot)) {
94
+ // A requirement is rewritten only when it points at a crate this run
95
+ // actually bumped. The workspace root routinely declares members the
96
+ // artifact never compiles; pinning those to the release version would
97
+ // name a version nothing produced.
98
+ if (!dep.hasVersionReq || !bumped.has(dep.dir)) {
99
+ continue;
100
+ }
101
+ updated = replaceDepVersionReq(updated, dep.key, version);
102
+ }
103
+ if (updated !== manifest.source) {
104
+ const cargoPath = join(dir, 'Cargo.toml');
105
+ await writeFile(cargoPath, updated, 'utf8');
106
+ written.add(cargoPath);
107
+ }
108
+ }
109
+ return [...written];
110
+ }
111
+ /**
112
+ * Breadth-first walk of path dependencies out of `startDir`. Returns the
113
+ * crates reached, excluding `startDir` — seeding `seen` with it also keeps
114
+ * a dependency cycle back to the start from re-queueing forever.
115
+ */
116
+ async function collectEmbedded(startDir, workspaceParsed, workspaceRoot) {
117
+ const seen = new Set([startDir]);
118
+ const found = new Set();
119
+ const queue = [startDir];
120
+ while (queue.length > 0) {
121
+ const dir = queue.shift();
122
+ const manifest = await readManifest(dir);
123
+ if (manifest === null) {
124
+ continue;
125
+ }
126
+ for (const dep of resolveDepDirs(manifest.parsed, dir, workspaceParsed, workspaceRoot)) {
127
+ if (seen.has(dep.dir)) {
128
+ continue;
129
+ }
130
+ seen.add(dep.dir);
131
+ found.add(dep.dir);
132
+ queue.push(dep.dir);
133
+ }
134
+ }
135
+ return found;
136
+ }
137
+ /**
138
+ * Read and parse `<dir>/Cargo.toml`. Returns null when the file is absent
139
+ * or unparseable — a path dependency can point at a directory that is not
140
+ * a crate, and an odd-but-writable manifest should not abort the release.
141
+ *
142
+ * ENOENT is caught rather than pre-checked with `existsSync` to avoid the
143
+ * TOCTOU shape CodeQL flags, matching the rest of the version-write path.
144
+ * Any other read failure surfaces unmodified.
145
+ */
146
+ async function readManifest(dir) {
147
+ let source;
148
+ try {
149
+ source = await readFile(join(dir, 'Cargo.toml'), 'utf8');
150
+ }
151
+ catch (err) {
152
+ if (err.code === 'ENOENT') {
153
+ return null;
154
+ }
155
+ throw err;
156
+ }
157
+ try {
158
+ return { source, parsed: parseToml(source) };
159
+ }
160
+ catch {
161
+ return null;
162
+ }
163
+ }
164
+ /**
165
+ * A virtual manifest declares `[workspace]` but no crate to version.
166
+ * `parsed` always comes from `readManifest`, which yields a parsed TOML
167
+ * document or null, so the null case never reaches here.
168
+ */
169
+ function hasPackageTable(parsed) {
170
+ return typeof parsed.package === 'object';
171
+ }
172
+ //# sourceMappingURL=write-embedded-crate-versions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write-embedded-crate-versions.js","sourceRoot":"","sources":["../src/write-embedded-crate-versions.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"write-version.d.ts","sourceRoot":"","sources":["../src/write-version.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAcH;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAmD7F"}
1
+ {"version":3,"file":"write-version.d.ts","sourceRoot":"","sources":["../src/write-version.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAeH;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAwD7F"}
@@ -21,6 +21,7 @@ import { join } from 'node:path';
21
21
  import { parse as parseToml } from 'smol-toml';
22
22
  import { ErrorCodes } from './error-codes.js';
23
23
  import { toError } from './to-error.js';
24
+ import { writeEmbeddedCrateVersions } from './write-embedded-crate-versions.js';
24
25
  import { writeResolvedCargoVersion } from './write-resolved-cargo-version.js';
25
26
  const DYNAMIC_VERSION_DOC_POINTER = 'https://thekevinscott.github.io/putitoutthere/guide/dynamic-versions';
26
27
  /**
@@ -81,7 +82,12 @@ export async function writeVersionForBuild(pkgDir, version) {
81
82
  }
82
83
  throw toError(err);
83
84
  }
84
- return await writeResolvedCargoVersion(pkgDir, cargoOriginal, version);
85
+ const written = await writeResolvedCargoVersion(pkgDir, cargoOriginal, version);
86
+ // #621: the wheel embeds every in-repo crate the extension module pulls
87
+ // in by path. When the CLI lives in one of those (a Rust core wrapped by
88
+ // this pyo3 crate), its `CARGO_PKG_VERSION` is what `--version` prints.
89
+ const embedded = await writeEmbeddedCrateVersions(pkgDir, version);
90
+ return [...new Set([...written, ...embedded])];
85
91
  }
86
92
  function isDynamicVersion(project) {
87
93
  const { dynamic } = project;
@@ -1 +1 @@
1
- {"version":3,"file":"write-version.js","sourceRoot":"","sources":["../src/write-version.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"write-version.js","sourceRoot":"","sources":["../src/write-version.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "putitoutthere",
3
- "version": "0.3.8",
3
+ "version": "0.3.9",
4
4
  "description": "Polyglot release orchestrator for crates.io, PyPI, and npm",
5
5
  "license": "MIT",
6
6
  "repository": {