-
Notifications
You must be signed in to change notification settings - Fork 46
Expand file tree
/
Copy pathCargo.toml
More file actions
181 lines (173 loc) · 9.71 KB
/
Copy pathCargo.toml
File metadata and controls
181 lines (173 loc) · 9.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
[workspace]
members = ["crates/nub-cache-key", "crates/nub-cli", "crates/nub-core", "crates/nub-phantom-core", "crates/nub-phantom-scan"]
# vendor/aube is its own Cargo workspace (the vendored aube package manager,
# plain in-tree files vendored from nubjs/aube). The exclude is load-bearing: nub crates
# take `path` dependencies into vendor/aube/crates/*, and cargo auto-adopts
# path deps living under the workspace directory as members unless excluded —
# which would collide with aube's own [workspace] root. Excluded, the aube
# crates still build as path deps (resolved into THIS workspace's Cargo.lock)
# while their `workspace = true` field inheritance resolves against
# vendor/aube/Cargo.toml.
#
# crates/nub-native is ALSO its own Cargo workspace, for a panic-strategy reason
# (NOT a path-collision one): Cargo's `panic` setting is profile-GLOBAL within a
# workspace, but nub-native (a cdylib loaded INTO the user's Node process via
# napi) MUST stay `panic = "unwind"` — abort-on-panic there would kill the host
# Node process instead of surfacing a JS error — while the `nub` CLI binary
# (which only ever `process::exit`s and never relies on unwinding) wants
# `panic = "abort"` to drop the unwind metadata and shrink the binary. The two
# strategies can't coexist in one workspace's release profile, so nub-native
# lives in its own workspace (crates/nub-native/Cargo.toml) with its own
# `[profile.release] panic = "unwind"`, and is excluded here. It is built
# directly (`--manifest-path crates/nub-native/Cargo.toml`); its `.cargo/config.toml`
# routes output to this same root `target/` so the addon-copy paths are unchanged.
# nub-native depends on `crates/nub-cache-key` (which stays a member here) via a
# path dep that crosses the workspace boundary — the cache-key crate's
# `workspace = true` inheritance resolves against THIS workspace, and nub-native
# recompiles it under its own unwind profile for the final cdylib.
#
# crates/nub-phantom is an INTERNAL/eval tool (the phantom-dependency ecosystem
# scanner over published npm tarballs), NOT part of the shipped `nub` binary. It
# is its own single-member workspace, excluded here, because it pulls the
# registry-fetch stack (reqwest/tar/flate2) plus its own binary — build weight
# the CLI never needs. It no longer carries its own copy of the scan pipeline:
# it depends on crates/nub-phantom-scan (the CLI's reachable-graph scanner, a
# member below) for the graph walk + classifier + manifest parser, which in turn
# shares the precision-critical extraction primitives in crates/nub-phantom-core
# — so the eval tool and the shipped scan can't diverge. Built on demand:
# `cargo build --manifest-path crates/nub-phantom/Cargo.toml --release`.
#
# crates/nub-phantom-scan (a MEMBER, not excluded) is the shipped CLI's
# reachable-graph phantom scanner, and crates/nub-phantom-core (also a MEMBER)
# holds the shared specifier-extraction/classification primitives. Core depends
# on the LEAN oxc parser subset (oxc_parser/oxc_ast/oxc_ast_visit/oxc_span/
# oxc_allocator), NOT the `oxc` umbrella with features=["full"] — so linking it
# into the CLI adds the parser, not the transformer/codegen/semantic/minifier
# tail. See their Cargo.toml files.
exclude = ["vendor/aube", "crates/nub-native", "crates/nub-phantom"]
resolver = "3"
# Tier-0 release tuning. `panic = "abort"` drops the unwind tables/metadata from
# the `nub` CLI binary — it always `process::exit`s and never relies on stack
# unwinding (no `catch_unwind` on a CLI-side panic). The N-API cdylib, which DOES
# require unwind (see the exclude comment above), lives in its own workspace and
# keeps `panic = "unwind"`; that is the whole reason for the split. Governs the
# nub workspace only; vendor/aube and crates/nub-native are separate workspaces.
[profile.release]
opt-level = 3
lto = "thin"
codegen-units = 1
strip = true
panic = "abort"
# Fast local-iteration profile for `nub-dev` / `make install-dev`. NOT a ship
# profile — the release block above is untouched. Inherits `dev` (debug
# assertions + overflow checks stay on), but drops everything the release build
# pays for serial-tail codegen: no LTO, many codegen units, line-tables-only
# debuginfo. nub-cli is the most-edited crate AND the release build's ~300s
# critical-path tail (lto=thin + cgu=1); the fast profile recompiles+links it in
# a fraction of that (measured ~20-34x faster incremental rebuild).
[profile.fast]
inherits = "dev"
opt-level = 0
debug = "line-tables-only"
codegen-units = 256
incremental = true
# Optimize DEPENDENCIES even in dev/fast so the dev binary stays usable at
# runtime (the oxc transpile + aube install paths are perf-sensitive). Our own
# crates stay at the profile opt-level (0) for fast recompiles; deps are cached
# so this costs nothing incrementally.
[profile.dev.package."*"]
opt-level = 2
[profile.fast.package."*"]
opt-level = 2
# macOS: keep debuginfo in the .o files instead of running dsymutil on every
# link (a .dSYM bundle build per link is pure dev-iteration overhead).
[profile.dev]
split-debuginfo = "unpacked"
[workspace.package]
version = "0.4.13"
edition = "2024"
rust-version = "1.93"
license = "MIT"
repository = "https://github.com/nubjs/nub"
[workspace.dependencies]
anyhow = "1"
# Benchmark harness (dev-only). `harness = false` benches drive criterion's own
# main(); see crates/*/benches and benches/README.md.
criterion = "0.5"
camino = "1"
ctrlc = "3"
libc = "0.2"
clap = { version = "4", features = ["derive"] }
dirs-next = "2"
json5 = "0.4"
# Reads (`serde`) + comment/order-preserving read-modify-write (`cst`) of JSONC —
# the transpiler's tsconfig parsing and nub's own global config file
# (~/.config/nub/nub.jsonc).
jsonc-parser = { version = "0.24", features = ["serde", "cst"] }
# napi 3 (not 2): oxc_napi 0.132.0 and oxc_sourcemap[napi] are built against
# napi 3, and a single cdylib cannot mix napi-2 and napi-3 `#[napi]` derives
# (the OxcError / SourceMap return types would fail to bridge). napi 3 is the
# version oxc itself ships on. The `napi8` feature pins the NAPI-version FLOOR to
# 8 (node_api_version 8 — available since Node 12.22/14.12/15.0, comfortably below
# the 18.19 floor) so any accidental higher-API use fails at compile-time rather
# than at load on 18.19. serde-json preserves the bridge the data parsers rely on.
napi = { version = "3", features = ["serde-json", "napi8"] }
napi-derive = "3"
# oxc transpiler — pinned EXACT to the oxc-transform npm version nub ships today
# (see package.json: oxc-transform/oxc-parser/@oxc-project/runtime are all 0.132.0).
# The internal Rust crates carry the SAME version number as the napi release;
# oxc_sourcemap is independently versioned (oxc_codegen 0.132.0 depends on
# oxc_sourcemap ^6.0.1). Any oxc bump must move in lockstep with the npm pin AND a
# NUB_VERSION bump (transpile-cache buster). DO NOT float without re-running the
# transpile-parity gate. OXC_VERSION = 0.132.0
oxc = { version = "=0.132.0", features = ["full"] }
oxc_napi = "=0.132.0"
oxc_sourcemap = { version = "=6.0.1", features = ["napi"] }
rustc-hash = "2"
toml = "0.8"
# Interactive terminal primitive (raw-mode key reads, cursor control) for the
# dlx consent radio in nubx_consent.rs. Already compiled in via `demand` (aube's
# build-approval picker) → direct dep reuses the same crate (no new build).
console = "0.16"
yaml-rust2 = "0.9"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
sha2 = "0.10"
# blake3 content hash for the transpile-cache key + integrity prefix (SIMD,
# replaced SHA-256 on the warm path; schema v4).
blake3 = "1"
# Node provisioning download (wiki/research/node-provisioning-implementation.md):
# blocking + rustls (no OpenSSL/cross-compile pain), native roots so corporate
# MITM CAs work, socks for SOCKS proxies. reqwest gives HTTP(S)_PROXY/NO_PROXY
# for free. NOT async — provisioning is a short at-most-once-per-version step.
reqwest = { version = "0.12", default-features = false, features = ["blocking", "rustls-tls", "rustls-tls-native-roots", "socks"] }
# xz extraction of the dist tarball. liblzma's "static" vendors its own C liblzma
# (no system dependency, no shell-out to tar/xz); the maintained xz2 successor.
liblzma = { version = "0.4", features = ["static"] }
# gzip decode of PM registry tarballs (npm publishes .tgz = gzip+tar). zlib-ng
# backend (built from bundled C via cmake/cc), no system zlib / shell-out —
# mirrors the in-process, verify-then-extract posture of the Node xz path.
flate2 = { version = "1", default-features = false, features = ["zlib-ng"] }
tar = "0.4"
# Windows .zip Node-dist extraction (pure Rust, no shell-out to Expand-Archive /
# tar.exe). default-features off + `deflate` only: Node's win-<arch>.zip uses
# DEFLATE, so we skip bzip2/zstd/lzma/aes backends and their C deps. Keeps the
# checksum-verify-then-extract flow in one process, deterministic across Windows
# versions. Builds on every target; the .zip path just isn't exercised on unix.
zip = { version = "8.6", default-features = false, features = ["deflate"] }
thiserror = "2"
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
# Workspace restriction lints, promoted to warn and inherited by every nub crate
# (each opts in with `[lints] workspace = true`). CI runs clippy under
# `-D warnings`, so each is a hard gate. Scope is deliberately MINIMAL: only the
# zero-violation, high-signal markers that flag unfinished/debug code shipping
# to users. Deliberately OMITTED (measured 2026-06-21, would need a large
# refactor, not a review-miss guard): `print_stdout`/`print_stderr` (a CLI
# legitimately prints and there is no output wrapper — 239 sites); `unwrap_used`/
# `expect_used`/`panic`/`exit` (1300+ sites, mostly tests). Revisit those behind
# an output wrapper / `allow-in-tests` later.
[workspace.lints.clippy]
dbg_macro = "warn"
todo = "warn"
unimplemented = "warn"