mirror of
https://github.com/pnpm/pnpm.git
synced 2026-07-19 20:22:21 -04:00
Strict minimumReleaseAge resolution already collects every immature pick, but pacquet could only abort. Add the interactive approval path used by the TypeScript CLI, persist approved exclusions before install writes begin, and keep noninteractive installs fail-closed with the complete violation list. Run the blocking confirmation off the async worker and bracket it with pnpm:prompt events. The default reporter holds append-only lines or the latest live frame while the question is active, then replays that output when prompting ends. Reject update --no-save up front because approval requires a durable workspace exclusion. Closes pnpm/pnpm#13047.
298 lines
17 KiB
TOML
298 lines
17 KiB
TOML
[workspace]
|
|
resolver = "2"
|
|
members = ["pnpm/crates/*", "pnpm/tasks/*", "pnpr/crates/*"]
|
|
|
|
[workspace.package]
|
|
authors = ["Yagiz Nizipli <yagiz@nizipli.com"]
|
|
description = "Pacquet"
|
|
edition = "2024"
|
|
homepage = "https://github.com/pnpm/pacquet"
|
|
keywords = ["nodejs", "package", "manager", "pnpm", "npm"]
|
|
license = "MIT"
|
|
repository = "https://github.com/pnpm/pacquet"
|
|
|
|
[workspace.dependencies]
|
|
# Crates
|
|
pacquet-pnpr-client = { path = "pnpm/crates/pnpr-client" }
|
|
pacquet-auth-commands = { path = "pnpm/crates/auth-commands" }
|
|
pacquet-catalogs-config = { path = "pnpm/crates/catalogs-config" }
|
|
pacquet-catalogs-protocol-parser = { path = "pnpm/crates/catalogs-protocol-parser" }
|
|
pacquet-catalogs-resolver = { path = "pnpm/crates/catalogs-resolver" }
|
|
pacquet-catalogs-types = { path = "pnpm/crates/catalogs-types" }
|
|
pacquet-cli = { path = "pnpm/crates/cli" }
|
|
pacquet-cmd-shim = { path = "pnpm/crates/cmd-shim" }
|
|
pacquet-crypto-hash = { path = "pnpm/crates/crypto-hash" }
|
|
pacquet-crypto-shasums-file = { path = "pnpm/crates/crypto-shasums-file" }
|
|
pacquet-engine-runtime-bun-resolver = { path = "pnpm/crates/engine-runtime-bun-resolver" }
|
|
pacquet-engine-runtime-deno-resolver = { path = "pnpm/crates/engine-runtime-deno-resolver" }
|
|
pacquet-engine-runtime-node-resolver = { path = "pnpm/crates/engine-runtime-node-resolver" }
|
|
pacquet-env-installer = { path = "pnpm/crates/env-installer" }
|
|
pacquet-env-replace = { path = "pnpm/crates/env-replace" }
|
|
pacquet-fs = { path = "pnpm/crates/fs" }
|
|
pacquet-fs-packlist = { path = "pnpm/crates/fs-packlist" }
|
|
pacquet-registry = { path = "pnpm/crates/registry" }
|
|
pacquet-tarball = { path = "pnpm/crates/tarball" }
|
|
pacquet-testing-utils = { path = "pnpm/crates/testing-utils" }
|
|
pacquet-pack = { path = "pnpm/crates/pack" }
|
|
pacquet-publish = { path = "pnpm/crates/publish" }
|
|
pacquet-package-manifest = { path = "pnpm/crates/package-manifest" }
|
|
pacquet-package-manager = { path = "pnpm/crates/package-manager" }
|
|
pacquet-package-is-installable = { path = "pnpm/crates/package-is-installable" }
|
|
pacquet-lockfile = { path = "pnpm/crates/lockfile" }
|
|
pacquet-lockfile-preferred-versions = { path = "pnpm/crates/lockfile-preferred-versions" }
|
|
pacquet-lockfile-verification = { path = "pnpm/crates/lockfile-verification" }
|
|
pacquet-modules-yaml = { path = "pnpm/crates/modules-yaml" }
|
|
pacquet-network = { path = "pnpm/crates/network" }
|
|
pacquet-napi = { path = "pnpm/crates/napi" }
|
|
pacquet-network-web-auth = { path = "pnpm/crates/network-web-auth" }
|
|
pacquet-network-web-auth-testing = { path = "pnpm/crates/network-web-auth-testing" }
|
|
pacquet-config = { path = "pnpm/crates/config" }
|
|
pacquet-config-dir = { path = "pnpm/crates/config-dir" }
|
|
pacquet-config-parse-overrides = { path = "pnpm/crates/config-parse-overrides" }
|
|
pacquet-default-reporter = { path = "pnpm/crates/default-reporter" }
|
|
pacquet-executor = { path = "pnpm/crates/executor" }
|
|
pacquet-exportable-manifest = { path = "pnpm/crates/exportable-manifest" }
|
|
pacquet-directory-fetcher = { path = "pnpm/crates/directory-fetcher" }
|
|
pacquet-git-fetcher = { path = "pnpm/crates/git-fetcher" }
|
|
pacquet-global = { path = "pnpm/crates/global" }
|
|
pacquet-deps-path = { path = "pnpm/crates/deps-path" }
|
|
pacquet-detect-libc = { path = "pnpm/crates/detect-libc" }
|
|
pacquet-diagnostics = { path = "pnpm/crates/diagnostics" }
|
|
pacquet-graph-hasher = { path = "pnpm/crates/graph-hasher" }
|
|
pacquet-hooks = { path = "pnpm/crates/hooks" }
|
|
pacquet-store-dir = { path = "pnpm/crates/store-dir" }
|
|
pacquet-reporter = { path = "pnpm/crates/reporter" }
|
|
pacquet-patching = { path = "pnpm/crates/patching" }
|
|
pacquet-real-hoist = { path = "pnpm/crates/real-hoist" }
|
|
pacquet-resolving-default-resolver = { path = "pnpm/crates/resolving-default-resolver" }
|
|
pacquet-resolving-deps-resolver = { path = "pnpm/crates/resolving-deps-resolver" }
|
|
pacquet-resolving-git-resolver = { path = "pnpm/crates/resolving-git-resolver" }
|
|
pacquet-resolving-jsr-specifier-parser = { path = "pnpm/crates/resolving-jsr-specifier-parser" }
|
|
pacquet-resolving-local-resolver = { path = "pnpm/crates/resolving-local-resolver" }
|
|
pacquet-resolving-npm-resolver = { path = "pnpm/crates/resolving-npm-resolver" }
|
|
pacquet-resolving-parse-wanted-dependency = { path = "pnpm/crates/resolving-parse-wanted-dependency" }
|
|
pacquet-resolving-resolver-base = { path = "pnpm/crates/resolving-resolver-base" }
|
|
pacquet-resolving-tarball-resolver = { path = "pnpm/crates/resolving-tarball-resolver" }
|
|
pacquet-versioning = { path = "pnpm/crates/versioning" }
|
|
pacquet-workspace = { path = "pnpm/crates/workspace" }
|
|
pacquet-workspace-manifest-writer = { path = "pnpm/crates/workspace-manifest-writer" }
|
|
pacquet-workspace-projects-filter = { path = "pnpm/crates/workspace-projects-filter" }
|
|
pacquet-workspace-projects-graph = { path = "pnpm/crates/workspace-projects-graph" }
|
|
pacquet-workspace-range-resolver = { path = "pnpm/crates/workspace-range-resolver" }
|
|
pacquet-workspace-spec = { path = "pnpm/crates/workspace-spec" }
|
|
pacquet-workspace-state = { path = "pnpm/crates/workspace-state" }
|
|
|
|
# Tasks
|
|
pacquet-registry-mock = { path = "pnpm/tasks/registry-mock" }
|
|
|
|
# Registry (sibling project — pnpm-compatible registry server)
|
|
pnpr = { path = "pnpr/crates/pnpr" }
|
|
pnpr-fixtures = { path = "pnpr/crates/pnpr-fixtures" }
|
|
|
|
# Dependencies
|
|
async-recursion = { version = "1.1.1" }
|
|
async-trait = { version = "0.1.83" }
|
|
axum = { version = "0.8.7", default-features = false, features = [
|
|
"http1",
|
|
"tokio",
|
|
"json",
|
|
"matched-path",
|
|
"original-uri",
|
|
] }
|
|
clap = { version = "4", features = ["derive", "string"] }
|
|
command-extra = { version = "1.0.0" }
|
|
base64 = { version = "0.22.1" }
|
|
bcrypt = { version = "0.19.1" }
|
|
bytes = { version = "1.11.0" }
|
|
chrono = { version = "0.4.44", default-features = false, features = ["clock"] }
|
|
crossterm = { version = "0.29.0" }
|
|
dashmap = { version = "6.2.1" }
|
|
derive_more = { version = "2.1.1", features = ["full"] }
|
|
dialoguer = { version = "0.12.0", default-features = false }
|
|
diffy = { version = "0.5.0" }
|
|
dunce = { version = "1.0.5" }
|
|
home = { version = "0.5.12" }
|
|
httpdate = { version = "1.0.3" }
|
|
ignore = { version = "0.4.25" }
|
|
indexmap = { version = "2.14.0", features = ["serde"] }
|
|
insta = { version = "1.47.2", features = ["yaml", "glob", "walkdir"] }
|
|
is_ci = { version = "1.2.0" }
|
|
itertools = { version = "0.15.0" }
|
|
libsql = { version = "0.9.30", default-features = false, features = ["core", "remote", "replication"] }
|
|
futures-util = { version = "0.3.32" }
|
|
flate2 = { version = "1.1.9" }
|
|
gethostname = { version = "1" }
|
|
getrandom = { version = "0.4.2" }
|
|
miette = { version = "7.6.0", features = ["fancy"] }
|
|
napi = { version = "3.10.3", default-features = false, features = ["napi8", "serde-json", "tokio_rt", "async"] }
|
|
napi-build = { version = "2.3.2" }
|
|
napi-derive = { version = "3.5.9" }
|
|
num_cpus = { version = "1.17.0" }
|
|
object_store = { version = "0.13", features = ["aws"] }
|
|
open = { version = "5.3.5" }
|
|
os_display = { version = "0.1.4" }
|
|
owo-colors = { version = "4", features = ["supports-colors"] }
|
|
reflink-copy = { version = "0.1.29" }
|
|
junction = { version = "2.0.0" }
|
|
libc = { version = "0.2.186" }
|
|
reqwest = { version = "0.13", default-features = false, features = [
|
|
"gzip",
|
|
"hickory-dns",
|
|
"json",
|
|
"rustls",
|
|
"socks",
|
|
"stream",
|
|
] }
|
|
node-semver = { version = "2.2.0" }
|
|
p256 = { version = "0.13.2", default-features = false, features = ["ecdsa", "pkcs8", "std"] }
|
|
pathdiff = { version = "0.2.3" }
|
|
pipe-trait = { version = "0.4.0" }
|
|
pgp = { version = "0.20.0", default-features = false }
|
|
qrcode = { version = "0.14.1", default-features = false }
|
|
rayon = { version = "1.12.0" }
|
|
rmp-serde = { version = "1.3.0" }
|
|
rusqlite = { version = "0.39.0", features = ["bundled"] }
|
|
same-file = { version = "1.0.6" }
|
|
serde = { version = "1.0.228", features = ["derive"] }
|
|
serde_json = { version = "1.0.150", features = ["preserve_order", "raw_value"] }
|
|
serde-saphyr = { version = "0.0.27" }
|
|
sqlx = { version = "0.8.6", default-features = false, features = ["runtime-tokio-rustls"] }
|
|
# 0.11 removes the LowerHex impl on Output; revisit after upstream/consumers catch up
|
|
sha2 = { version = "0.10.9" }
|
|
sigstore-sign = { version = "0.10.0" }
|
|
smart-default = { version = "0.7.1" }
|
|
split-first-char = { version = "2.0.1" }
|
|
ssri = { version = "9.2.0" }
|
|
strum = { version = "0.28.0", features = ["derive"] }
|
|
sysinfo = { version = "0.39.2" }
|
|
tabled = { version = "0.21" }
|
|
tar = { version = "0.4.46" }
|
|
text-block-macros = { version = "0.2.0" }
|
|
tower = { version = "0.5.3" }
|
|
tower-http = { version = "0.7.0", features = ["compression-gzip", "trace"] }
|
|
tracing = { version = "0.1.44" }
|
|
tracing-subscriber = { version = "0.3.23", features = ["env-filter"] }
|
|
tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros", "fs", "io-util", "net", "signal", "sync"] }
|
|
url = { version = "2.5.8" }
|
|
walkdir = { version = "2.5.0" }
|
|
windows-sys = { version = "0.61", features = ["Win32_Foundation", "Win32_System_JobObjects", "Win32_System_Threading"] }
|
|
yaml_serde = { version = "0.10.4" }
|
|
yamlpatch = { version = "1.25.2" }
|
|
yamlpath = { version = "1.25.2" }
|
|
wax = { version = "0.7.0" }
|
|
which = { version = "8.0.2" }
|
|
zip = { version = "8", default-features = false, features = ["deflate"] }
|
|
zune-inflate = { version = "0.2.54" }
|
|
|
|
# Dev dependencies
|
|
assert_cmd = { version = "2.2.2" }
|
|
criterion = { version = "0.8.2", features = ["async_tokio"] }
|
|
pretty_assertions = { version = "1.4.1" }
|
|
project-root = { version = "0.2.2" }
|
|
tempfile = { version = "3.27.0" }
|
|
mockito = { version = "1.7.2" }
|
|
|
|
[workspace.metadata.workspaces]
|
|
allow_branch = "main"
|
|
|
|
# Declares the `dylint_lib = "perfectionist"` cfg used by the
|
|
# `cfg_attr(dylint_lib = "perfectionist", feature(register_tool))` /
|
|
# `register_tool(perfectionist)` lines at each pacquet crate's root.
|
|
# Those `cfg_attr`s register the perfectionist tool name under dylint's
|
|
# nightly toolchain (so `#[expect(perfectionist::lint, reason = "...")]`
|
|
# at use sites compiles cleanly without a wrapper); this `check-cfg`
|
|
# entry tells stable `cargo check` that the cfg name is expected even
|
|
# though it's never set off-dylint.
|
|
[workspace.lints.rust]
|
|
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(dylint_lib, values("perfectionist"))'] }
|
|
|
|
[workspace.lints.clippy]
|
|
pedantic = { level = "warn", priority = -1 }
|
|
nursery = { level = "warn", priority = -1 }
|
|
|
|
doc_link_with_quotes = "allow" # false positive: matches markdown link titles
|
|
unreadable_literal = "allow" # false positive: octal file modes
|
|
case_sensitive_file_extension_comparisons = "allow" # extension checks are intentionally case-sensitive
|
|
implicit_hasher = "allow" # only matters across a public API
|
|
unnecessary_debug_formatting = "allow" # keeps the quoted `Path` output
|
|
option_option = "allow" # distinguishes missing from null
|
|
cast_possible_truncation = "allow" # deliberate numeric narrowing
|
|
cast_sign_loss = "allow"
|
|
cast_possible_wrap = "allow"
|
|
cast_precision_loss = "allow"
|
|
missing_errors_doc = "allow" # error enums are self-documenting (#[display] + #[diagnostic(code)]); a # Errors section would just restate them
|
|
missing_panics_doc = "allow" # deferred: refactor away / document / #[expect] each panic before enabling
|
|
too_many_lines = "allow" # pacquet mirrors pnpm's function decomposition
|
|
struct_excessive_bools = "allow" # option structs mirror pnpm's
|
|
fn_params_excessive_bools = "allow" # mirrors pnpm's option parameters
|
|
match_same_arms = "allow" # arms kept explicit to mirror pnpm's switch cases
|
|
unnecessary_wraps = "allow"
|
|
unused_async = "allow" # deferred: audit each async signature (trait/seam-required?) before enabling
|
|
similar_names = "allow" # names ported verbatim from pnpm
|
|
items_after_statements = "allow"
|
|
needless_continue = "allow"
|
|
many_single_char_names = "allow" # perfectionist's single_letter_* lints already cover this with finer per-position control
|
|
|
|
# nursery-group opt-outs (the group is experimental; these lints are either
|
|
# false positives on this code or fight conventions the project keeps on purpose)
|
|
use_self = "allow" # spelling out the concrete type name over Self is left to author discretion
|
|
too_long_first_doc_paragraph = "allow" # doc comments deliberately open with a detailed pnpm-parity summary, not a one-line lede
|
|
missing_const_for_fn = "allow" # const-ness is a forward semver commitment and this nursery lint is noisy / churns as const-eval grows
|
|
option_if_let_else = "allow" # the suggested map_or_else closures read worse than the if-let they replace
|
|
significant_drop_tightening = "allow" # the flagged guards are held deliberately (atomic check-then-act); early-dropping is FP-prone and behavioral
|
|
redundant_pub_crate = "allow" # pub(crate) is kept to document intended visibility even where technically redundant
|
|
derive_partial_eq_without_eq = "allow" # deriving Eq is a forward semver commitment that all fields stay Eq
|
|
branches_sharing_code = "allow" # false-positive-prone: clippy itself flags its own suggestion as needing adjustment
|
|
useless_let_if_seq = "allow" # rewrites large init blocks into an awkward if-as-expression
|
|
single_option_map = "allow" # flags test helpers that exist precisely to dedupe a `.map` over an Option
|
|
iter_with_drain = "allow" # false positive: drain(..) reuses the batch Vec's allocation across loop iterations; into_iter() would consume it
|
|
literal_string_with_formatting_args = "allow" # false positive: `${VAR:-default}` strings are .npmrc / env-replace fixtures, not Rust format args
|
|
collection_is_never_read = "allow" # false positive: the flagged Vec owns sockets to keep them alive, it is never meant to be read
|
|
|
|
# restriction lints opted into individually — not part of any default group or
|
|
# the nursery group, so these lines are what enable them (kept on purpose).
|
|
clone_on_ref_ptr = "warn"
|
|
if_then_some_else_none = "warn"
|
|
mod_module_files = "warn" # forbids mod.rs, enforcing the flat module.rs layout (see CODE_STYLE_GUIDE.md)
|
|
undocumented_unsafe_blocks = "warn"
|
|
unnecessary_safety_comment = "warn"
|
|
todo = "warn"
|
|
unimplemented = "warn"
|
|
exit = "warn"
|
|
infinite_loop = "warn"
|
|
mem_forget = "warn"
|
|
unused_result_ok = "warn"
|
|
pathbuf_init_then_push = "warn"
|
|
string_add = "warn"
|
|
verbose_file_reads = "warn"
|
|
|
|
# cargo-group lints opted into individually (the cargo group is otherwise off).
|
|
negative_feature_names = "warn"
|
|
redundant_feature_names = "warn"
|
|
wildcard_dependencies = "warn"
|
|
|
|
[profile.release]
|
|
opt-level = 3
|
|
lto = "fat"
|
|
codegen-units = 1
|
|
strip = "symbols"
|
|
debug = false
|
|
panic = "abort" # Let it crash and force ourselves to write safe Rust.
|
|
|
|
# Use the `--profile release-debug` flag to show symbols in release mode.
|
|
# e.g. `cargo build --profile release-debug`
|
|
[profile.release-debug]
|
|
inherits = "release"
|
|
strip = false
|
|
debug = true
|
|
|
|
# Profile for the Node.js NAPI addon (`pacquet-node-api`, a cdylib loaded
|
|
# into a host `node` process). The `release` profile above uses
|
|
# `panic = "abort"`, which would abort the entire host process on any Rust
|
|
# panic that unwinds to the FFI boundary. napi-rs catches unwinding panics
|
|
# and turns them into JS exceptions, so the addon must be built with
|
|
# `panic = "unwind"` instead.
|
|
[profile.napi-release]
|
|
inherits = "release"
|
|
panic = "unwind"
|