diff --git a/test/frontends/alpine.t/run.t b/test/frontends/alpine.t/run.t index ae73ecf..72f5471 100644 --- a/test/frontends/alpine.t/run.t +++ b/test/frontends/alpine.t/run.t @@ -1,6 +1,7 @@ -untimed drops the timings from pac's output and keeps its exit status: +untimed (../untimed.sh) drops the timings from pac's output and keeps its +exit status: - $ untimed() { "$@" > out 2>&1; s=$?; sed -E '/^(parse|solve) [0-9.]+s$/d' out; return $s; } + $ . ../untimed.sh $ untimed ../../../bin/main.exe alpine APKINDEX app docs packages (3): diff --git a/test/frontends/cargo.t/run.t b/test/frontends/cargo.t/run.t index 1f7fbab..603a235 100644 --- a/test/frontends/cargo.t/run.t +++ b/test/frontends/cargo.t/run.t @@ -1,9 +1,14 @@ +untimed (../untimed.sh) drops the timings from pac's output and keeps its +exit status: + + $ . ../untimed.sh + A query is a root Cargo.toml, as cargo has no other. Most cases below root a crate of the index through the manifest it was published with, manifests/.toml, so the root's own dev-dependencies and features are in play. - $ ../../../bin/main.exe cargo index manifests/a.toml | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe cargo index manifests/a.toml root a 1.0.0 packages (6): a 1.0.0 @@ -20,7 +25,7 @@ names a prerelease at the same release core. p publishes 1.0.0 and the newer 1.0.1-alpha, and ^1.0.0 names no prerelease, so it takes 1.0.0; q publishes 1.0.0-alpha.1 alone, which ^1.0.0-alpha reaches. - $ ../../../bin/main.exe cargo index manifests/g.toml | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe cargo index manifests/g.toml root g 1.0.0 packages (3): g 1.0.0 @@ -34,7 +39,7 @@ as an optional normal dependency and as a dev-dependency; from root h, k is not the root, so neither record installs m -- the optional one is never activated and the dev one does not participate. - $ ../../../bin/main.exe cargo index manifests/h.toml | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe cargo index manifests/h.toml root h 1.0.0 packages (2): h 1.0.0 @@ -48,7 +53,7 @@ resolve: the implicit feature of the optional m is among them, so that record activates as well and each of the two binds m through its own slot, two parent edges onto the one installed crate. - $ ../../../bin/main.exe cargo index manifests/k.toml | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe cargo index manifests/k.toml root k 1.0.0 packages (2): k 1.0.0 [m] @@ -63,7 +68,7 @@ mandatory dev record installs m by itself. The two stay separate slots -- conjoined, the dev record's non-optionality would bind on every depender, which is the h case above. - $ ../../../bin/main.exe cargo index manifests/k.toml --features "" | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe cargo index manifests/k.toml --features "" root k 1.0.0 with default features packages (2): k 1.0.0 @@ -79,7 +84,7 @@ known. z must still be admitted once it arrives -- the answer is the older, link-free x beside z, not a rejection of z against a version set fixed without it. - $ ../../../bin/main.exe cargo index manifests/r.toml | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe cargo index manifests/r.toml root r 1.0.0 packages (4): r 1.0.0 @@ -92,7 +97,7 @@ without it. The root's own links key excludes as a dependency's does. rl claims links=foo, so x 1.0.0, which claims it too, is out and x 0.9.0 is taken. - $ ../../../bin/main.exe cargo index manifests/rl.toml | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe cargo index manifests/rl.toml root rl 1.0.0 packages (2): rl 1.0.0 @@ -106,7 +111,7 @@ nowhere else; cargo's resolver activates such an entry unconditionally and narrows it only in a later pass over the fixed resolution, so that w keeps its place in the lock as --features varies, and w is installed with extra. - $ ../../../bin/main.exe cargo index manifests/s.toml | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe cargo index manifests/s.toml root s 1.0.0 packages (3): s 1.0.0 @@ -121,7 +126,7 @@ it does, and newest-first still decides within each of the two. d1 publishes 1.0.0 with rust-version 1.60 and 1.1.0 with 1.80; under a 1.70 toolchain m1 takes the older 1.0.0. - $ ../../../bin/main.exe cargo index manifests/m1.toml --rust-version 1.70 | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe cargo index manifests/m1.toml --rust-version 1.70 root m1 1.0.0 for rust 1.70 packages (2): d1 1.0.0 @@ -132,7 +137,7 @@ m1 takes the older 1.0.0. With no toolchain configured the preference is off, as it is in cargo when the rust-versions list is empty, and the same index takes the newest. - $ ../../../bin/main.exe cargo index manifests/m1.toml | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe cargo index manifests/m1.toml root m1 1.0.0 packages (2): d1 1.1.0 @@ -147,7 +152,7 @@ and 1.2.0 needing 1.95, so under 1.70 the field-less 1.1.0 wins -- neither the newest nor the oldest, which no other reading of the missing field would give. - $ ../../../bin/main.exe cargo index manifests/m2.toml --rust-version 1.70 | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe cargo index manifests/m2.toml --rust-version 1.70 root m2 1.0.0 for rust 1.70 packages (2): d2 1.1.0 @@ -155,7 +160,7 @@ would give. encoded solution: 6 core nodes (7 lookups) loaded: 2 names, 4 versions - $ ../../../bin/main.exe cargo index manifests/m2.toml | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe cargo index manifests/m2.toml root m2 1.0.0 packages (2): d2 1.2.0 @@ -167,7 +172,7 @@ This is a preference and not a constraint. m3 requires ^2 of d3, whose only version in range is 2.0.0 needing 1.90; the MSRV-compatible 1.0.0 is out of range, so 2.0.0 is taken rather than the solve failing. - $ ../../../bin/main.exe cargo index manifests/m3.toml --rust-version 1.70 | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe cargo index manifests/m3.toml --rust-version 1.70 root m3 1.0.0 for rust 1.70 packages (2): d3 2.0.0 @@ -182,7 +187,7 @@ declared it -- the target section, the kind table, and the key inside it -- so the two are separate rows of the summary and both resolve, giving a lockfile with e 0.1.0 beside e 0.2.0. - $ ../../../bin/main.exe cargo index manifests/t.toml | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe cargo index manifests/t.toml root t 1.0.0 packages (3): e 0.1.0 @@ -196,7 +201,7 @@ package = renames the target and the cross-table check constrains only the source registry. rn's x is e under [dependencies] and w under [target.'cfg(windows)'.dependencies], and both are installed. - $ ../../../bin/main.exe cargo index manifests/rn.toml | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe cargo index manifests/rn.toml root rn 1.0.0 packages (3): e 0.2.0 @@ -216,7 +221,7 @@ has one (dep_cache.rs, require_dep_feature): ir asks i for net alone, net is "o/extra" over the optional o, whose implicit feature o exists, so i is resolved with o on: - $ ../../../bin/main.exe cargo index manifests/ir.toml | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe cargo index manifests/ir.toml root ir 1.0.0 packages (3): i 1.0.0 [net,o] @@ -228,7 +233,7 @@ resolved with o on: Where dep:o names the dependency there is no implicit feature o to enable, and i3 is resolved with net alone: - $ ../../../bin/main.exe cargo index manifests/ir3.toml | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe cargo index manifests/ir3.toml root ir3 1.0.0 packages (3): i3 1.0.0 [net] @@ -245,7 +250,7 @@ crate's dependencies fewest candidates first and in declaration order between equals: ga is activated at 0.14.9, cp 0.1.7 then fails on its pin, and cp falls back to 0.1.6. - $ ../../../bin/main.exe cargo index manifests/oa.toml | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe cargo index manifests/oa.toml root oa 1.0.0 packages (4): cp 0.1.6 @@ -258,7 +263,7 @@ and cp falls back to 0.1.6. pb declares zp, a copy of cp, first, so zp 0.1.7 is activated first and its pin, with one candidate, is taken before pb's own ^0.14 of ga. - $ ../../../bin/main.exe cargo index manifests/ob.toml | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe cargo index manifests/ob.toml root ob 1.0.0 packages (4): ga 0.14.7 @@ -271,7 +276,7 @@ pin, with one candidate, is taken before pb's own ^0.14 of ga. The root's own dependencies are read from its manifest, whose tables cargo keys by name, so oc's zp-then-ga reaches the resolver as ga-then-zp. - $ ../../../bin/main.exe cargo index manifests/oc.toml | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe cargo index manifests/oc.toml root oc 1.0.0 packages (3): ga 0.14.9 @@ -288,7 +293,7 @@ ms activates sk 0.5.10 through its pin; mq's >=0.5, <0.7 then meets the compatible 0.5.9, which that activation rules out, and takes the newest of the rest, 0.6.5, although it needs a newer Rust than 1.70. - $ ../../../bin/main.exe cargo index manifests/ms.toml --rust-version 1.70 | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe cargo index manifests/ms.toml --rust-version 1.70 root ms 1.0.0 for rust 1.70 packages (4): mq 1.0.0 @@ -302,7 +307,7 @@ mu pins sl to 0.6.5, which needs 1.80, so mt's range skips the compatible 0.6.4 of that granularity class and takes the compatible 0.5.9 of the older one. - $ ../../../bin/main.exe cargo index manifests/mu.toml --rust-version 1.70 | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe cargo index manifests/mu.toml --rust-version 1.70 root mu 1.0.0 for rust 1.70 packages (4): mt 1.0.0 @@ -385,7 +390,7 @@ feature net asks i for net. The lock enables every root feature, so i comes in through net, with o behind i's own net, and e is locked at both 0.1.0 (for x) and 0.2.0. - $ ../../../bin/main.exe cargo index manifests/app.toml --print-parents | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe cargo index manifests/app.toml --print-parents root app 0.1.0 packages (9): app 0.1.0 [default,i,net] @@ -418,7 +423,7 @@ answers the second. $ ../../../bin/main.exe cargo index manifests/selfdep.toml > /dev/null error: the answer reaches b 1.0.0 through the registry, which cargo keeps apart from the root unless [patch.crates-io] maps b to it with { path = "." } [2] - $ ../../../bin/main.exe cargo index manifests/selfpatch.toml --print-parents | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe cargo index manifests/selfpatch.toml --print-parents root b 1.0.0 packages (6): a 1.0.0 @@ -452,7 +457,7 @@ An index entry whose feature table cargo's build_feature_map refuses is never a candidate, so cargo takes 1.0.0 of each of fa (dep:o/extra), fb (o/extra/z) and fc (a feature naming neither a feature nor a dependency): - $ ../../../bin/main.exe cargo index manifests/fm.toml | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe cargo index manifests/fm.toml root fm 1.0.0 packages (4): fa 1.0.0 @@ -480,7 +485,7 @@ names a surrogate rather than a Unicode scalar value: while dotted keys over one table, a sub-table header under them, and numbers TOML allows all read: - $ ../../../bin/main.exe cargo index manifests/tomlok.toml | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe cargo index manifests/tomlok.toml root tomlok 1.0.0 packages (4): b 1.0.0 @@ -494,7 +499,7 @@ A version component is a u64 in cargo's semver, so tv's timestamp-style 1.0.1234567890 and 1.0.1234567891 are two versions, and ^1 takes the newer, as cargo does. - $ ../../../bin/main.exe cargo index manifests/vt.toml | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe cargo index manifests/vt.toml root vt 1.0.0 packages (2): tv 1.0.1234567891 @@ -511,7 +516,7 @@ of bm's and bp's, and each name takes the greater: 1.0.0+b over 1.0.0+a, 1.0.0+9. bf's 1.0.0+b needs a crate the index lacks, so bf falls back to 1.0.0+a. cargo 1.97 locks the same six: - $ ../../../bin/main.exe cargo index manifests/bmeta.toml | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe cargo index manifests/bmeta.toml root bmeta 1.0.0 packages (6): bf 1.0.0+a @@ -523,12 +528,26 @@ of bm's and bp's, and each name takes the greater: 1.0.0+b over 1.0.0+a, encoded solution: 18 core nodes (23 lookups) loaded: 7 names, 10 versions +Nor does a greater-than bound take a version of the same precedence, so +bgt's >1.0.0 has nothing, as it has nothing in cargo, which fails with +"failed to select a version for the requirement". The explanation spells +the bound as the greatest version of its precedence, 1.0.0+*, a build no +version carries: + + $ untimed ../../../bin/main.exe cargo index manifests/bgt.toml + root bgt 1.0.0 + unsatisfiable: + Because root () -> bgt@1.0.0 1.0.0 and bgt@1.0.0 1.0.0 -> bgt@1.0.0->bm(>1.0.0+*) ∅, root * is forbidden.. + And because root -> root (), version solving failed. + loaded: 2 names, 2 versions + [1] + cargo skips an index line it cannot deserialize, so a line that is JSON but not an object is dropped and counted, and so is a version one of whose dependencies is not an object, or has no name: nb's 1.1.0 and 1.2.0 are out, and cargo, like pac, locks 1.0.0. - $ ../../../bin/main.exe cargo index manifests/nbr.toml | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe cargo index manifests/nbr.toml root nbr 1.0.0 packages (2): nb 1.0.0 @@ -542,7 +561,7 @@ it, as cargo's CliFeatures does, and an empty --features names nothing rather than everything. fd's default enables net, which asks the optional i for net. - $ ../../../bin/main.exe cargo index manifests/fd.toml | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe cargo index manifests/fd.toml root fd 1.0.0 packages (3): fd 1.0.0 [default,i,net,plain] @@ -550,7 +569,7 @@ optional i for net. o 1.0.0 [extra] encoded solution: 17 core nodes (17 lookups) loaded: 3 names, 2 versions - $ ../../../bin/main.exe cargo index manifests/fd.toml -F "" | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe cargo index manifests/fd.toml -F "" root fd 1.0.0 with default features packages (3): fd 1.0.0 [default,i,net] @@ -558,13 +577,13 @@ optional i for net. o 1.0.0 [extra] encoded solution: 16 core nodes (16 lookups) loaded: 3 names, 2 versions - $ ../../../bin/main.exe cargo index manifests/fd.toml --no-default-features | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe cargo index manifests/fd.toml --no-default-features root fd 1.0.0 with no features packages (1): fd 1.0.0 encoded solution: 2 core nodes (2 lookups) loaded: 2 names, 1 versions - $ ../../../bin/main.exe cargo index manifests/fd.toml --no-default-features -F plain | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe cargo index manifests/fd.toml --no-default-features -F plain root fd 1.0.0 with features plain and no default feature packages (1): fd 1.0.0 [plain] @@ -581,7 +600,7 @@ The order is cargo's unless --order=pubgrub leaves it to PubGrub, whose answer is a resolution too, though not always the one cargo locks: under PubGrub's own order oa keeps cp's newest, 0.1.7, and ga at its pin. - $ ../../../bin/main.exe cargo index manifests/oa.toml --order=pubgrub | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe cargo index manifests/oa.toml --order=pubgrub root oa 1.0.0 packages (4): cp 0.1.7 @@ -595,7 +614,7 @@ PubGrub's own order oa keeps cp's newest, 0.1.7, and ga at its pin. a generator seeded by --seed: the same seed gives the same answer, and another seed may give another, a resolution all the same: - $ seed0() { ../../../bin/main.exe cargo index manifests/oa.toml --order=random --seed 0 | sed -E '/^(parse|solve) [0-9.]+s$/d'; }; [ "$(seed0)" = "$(seed0)" ] && seed0 + $ seed0() { untimed ../../../bin/main.exe cargo index manifests/oa.toml --order=random --seed 0; }; [ "$(seed0)" = "$(seed0)" ] && seed0 root oa 1.0.0 packages (4): cp 0.1.6 @@ -604,7 +623,7 @@ another seed may give another, a resolution all the same: pa 1.0.0 encoded solution: 13 core nodes (16 lookups) loaded: 4 names, 6 versions - $ ../../../bin/main.exe cargo index manifests/oa.toml --order=random --seed 4 | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe cargo index manifests/oa.toml --order=random --seed 4 root oa 1.0.0 packages (4): cp 0.1.7 @@ -623,7 +642,7 @@ order, the two are one version, with both declarations' features: $ for s in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15; do ../../../bin/main.exe cargo index manifests/st.toml --order=random --seed $s | grep -c '^ wsy '; done | sort | uniq -c 16 1 - $ ../../../bin/main.exe cargo index manifests/st.toml --print-parents | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe cargo index manifests/st.toml --print-parents root st 1.0.0 packages (3): st 1.0.0 diff --git a/test/frontends/debian.t/run.t b/test/frontends/debian.t/run.t index 831472b..9e79980 100644 --- a/test/frontends/debian.t/run.t +++ b/test/frontends/debian.t/run.t @@ -1,6 +1,7 @@ -untimed drops the timings from pac's output and keeps its exit status: +untimed (../untimed.sh) drops the timings from pac's output and keeps its +exit status: - $ untimed() { "$@" > out 2>&1; s=$?; sed -E '/^(parse|solve) [0-9.]+s$/d' out; return $s; } + $ . ../untimed.sh Two providers of a name that differ in nothing apt ranks on -- no Essential or Important flag, the same architecture, the same Priority -- are separated by diff --git a/test/frontends/dune b/test/frontends/dune index f4062f8..5612921 100644 --- a/test/frontends/dune +++ b/test/frontends/dune @@ -1,2 +1,2 @@ (cram - (deps %{exe:../../bin/main.exe})) + (deps %{exe:../../bin/main.exe} untimed.sh)) diff --git a/test/frontends/npm.t/run.t b/test/frontends/npm.t/run.t index 78c5ed3..d257319 100644 --- a/test/frontends/npm.t/run.t +++ b/test/frontends/npm.t/run.t @@ -1,3 +1,8 @@ +untimed (../untimed.sh) drops the timings from pac's output and keeps its +exit status: + + $ . ../untimed.sh + A mandatory peer dependency is installed beside its declarer: app depends on plugin and widget but on neither core nor theme. plugin's peer on core is not optional, so core arrives as app's own sibling of plugin; widget's @@ -15,7 +20,7 @@ node. app's mandatory peer on runtime is installed at 1.1.0, the newest ^1, while its optional peer on polyfill is not installed even though polyfill is in the cache. - $ ../../../bin/main.exe npm --offline --cache . --tree ./app/package.json | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . --tree ./app/package.json root app 1.0.0 packages (7): app 1.0.0 @@ -42,7 +47,7 @@ declares a peer on dual <=1.2.0, and 1.3.0 installs, as the dependency alone picks it. shim is the same pair with the peer optional, and shim ^1 lands on 1.1.0. - $ ../../../bin/main.exe npm --offline --cache . --tree ./dual-app/package.json | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . --tree ./dual-app/package.json root dual-app 1.0.0 packages (3): dual 1.3.0 @@ -62,7 +67,7 @@ and so admits 1.0.0-alpha.1, while 2.0.0-beta.1 is refused even though the alternative >=1.5.0 <3.0.0 orders it in range, because that set names no prerelease and the set that does is the other alternative. - $ ../../../bin/main.exe npm --offline --cache . ./beta-app/package.json | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . ./beta-app/package.json root beta-app 1.0.0 packages (3): beta-app 1.0.0 @@ -80,7 +85,7 @@ the release 0.1.0. pre-depr's latest prerelease is deprecated and pre-engine's wants node >=99, so both fall back to 0.1.0, the release * admits without the exception. - $ ../../../bin/main.exe npm --offline --cache . --node-version v24.19.0 --npm-version 11.17.0 ./star-app/package.json | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . --node-version v24.19.0 --npm-version 11.17.0 ./star-app/package.json root star-app 1.0.0 packages (5): pre-ahead 1.0.0-alpha.0 @@ -95,7 +100,7 @@ npm's semver reads versions loosely, and a prerelease may drop its hyphen: 1.0.1rc1 is 1.0.1-rc1. loose tags it latest, but ^1.0.0 names no prerelease, so 1.0.0 is installed. - $ ../../../bin/main.exe npm --offline --cache . ./loose-app/package.json | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . ./loose-app/package.json root loose-app 1.0.0 packages (2): loose 1.0.0 @@ -117,7 +122,7 @@ native 1.0.0 depends on it, but nothing else does, so dropping the dependency takes it with it: transitivity needs no separate rule. - $ ../../../bin/main.exe npm --offline --cache . --tree ./opt-app/package.json | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . --tree ./opt-app/package.json root opt-app 1.0.0 packages (3): gadget 1.0.0 @@ -134,7 +139,7 @@ anything: gadget goes even though it resolves, and no availability check runs, so there is no optionalDependencies line and neither gadget nor native is loaded at all. - $ ../../../bin/main.exe npm --offline --cache . --tree --omit=optional ./opt-app/package.json | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . --tree --omit=optional ./opt-app/package.json root opt-app 1.0.0 packages (2): opt-app 1.0.0 @@ -152,7 +157,7 @@ tok 3.0.2 is placed before taker is reached, so taker's tok stays 3.0.2 though latest is 4.0.0, and host's peer gadget goes with host. npm 11.17.0 flags holder, host and gadget dev in its lock, and nothing else. - $ ../../../bin/main.exe npm --offline --cache . ./omit-app/package.json | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . ./omit-app/package.json root omit-app 1.0.0 packages (6): gadget 2.0.0 @@ -163,7 +168,7 @@ though latest is 4.0.0, and host's peer gadget goes with host. npm tok 3.0.2 encoded solution: 12 core nodes (14 lookups) loaded: 6 names, 8 versions, 0 packuments fetched - $ ../../../bin/main.exe npm --offline --cache . --tree --omit=dev ./omit-app/package.json | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . --tree --omit=dev ./omit-app/package.json root omit-app 1.0.0 packages (3): omit-app 1.0.0 @@ -191,7 +196,7 @@ fsevents, the best-known optional dependency, and npm puts it in the lockfile on linux too; dropping it here would make our answer smaller than npm's on every platform but macOS. - $ ../../../bin/main.exe npm --offline --cache . --tree ./opt-plat-app/package.json | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . --tree ./opt-plat-app/package.json root opt-plat-app 1.0.0 packages (4): native-core 1.0.0 @@ -211,7 +216,7 @@ nothing about the host enters ours. npm refuses this tree off darwin (EBADPLATFORM), even with --package-lock-only, so this pins our reading, not npm's answer. - $ ../../../bin/main.exe npm --offline --cache . --tree ./plat-app/package.json | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . --tree ./plat-app/package.json root plat-app 1.0.0 packages (4): native-core 1.0.0 @@ -230,9 +235,7 @@ opt-peer-app depends on host, whose peer on gadget is ^2, and optionally on gadget ^1; gadget publishes both, so the dependency's manifest is fetchable and the dependency stands. The two ranges fill the same directory and cannot agree, which is npm's ERESOLVE rather than a reason to abandon the entry. -(untimed drops the timings but keeps the status.) - $ untimed() { "$@" > out 2>&1; s=$?; sed -E '/^(parse|solve) [0-9.]+s$/d' out; return $s; } $ untimed ../../../bin/main.exe npm --offline --cache . --tree ./opt-peer-app/package.json root opt-peer-app 1.0.0 unsatisfiable: @@ -246,7 +249,7 @@ something else in the fixture, is what --omit=optional shows: with the dependency gone the peer installs gadget 2.0.0 by itself. - $ ../../../bin/main.exe npm --offline --cache . --tree --omit=optional ./opt-peer-app/package.json | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . --tree --omit=optional ./opt-peer-app/package.json root opt-peer-app 1.0.0 packages (3): gadget 2.0.0 @@ -265,7 +268,7 @@ directory only the peer asks for. The root overrides gadget to 1.0.0, which ^2 refuses, and 1.0.0 is what installs -- the override replaces a peer dependency's range exactly as it replaces a dependency's. - $ ../../../bin/main.exe npm --offline --cache . --tree ./ovr-peer-app/package.json | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . --tree ./ovr-peer-app/package.json root ovr-peer-app 1.0.0 packages (3): gadget 1.0.0 @@ -283,7 +286,7 @@ reads an empty value as *. ovr-star-app overrides tok to * and ovr-empty-app to "", and in both holder's ^3.0.0 still binds: tok 3.0.2, not the latest 4.0.0. - $ ../../../bin/main.exe npm --offline --cache . --tree ./ovr-star-app/package.json | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . --tree ./ovr-star-app/package.json root ovr-star-app 1.0.0 packages (3): holder 1.0.0 @@ -295,7 +298,7 @@ to "", and in both holder's ^3.0.0 still binds: tok 3.0.2, not the latest encoded solution: 5 core nodes (5 lookups) loaded: 3 names, 4 versions, 0 packuments fetched - $ ../../../bin/main.exe npm --offline --cache . --tree ./ovr-empty-app/package.json | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . --tree ./ovr-empty-app/package.json root ovr-empty-app 1.0.0 packages (3): holder 1.0.0 @@ -314,7 +317,7 @@ whose tok is ^3.0.0, and on taker, whose tok is ^3.0.0 || ^4.0.0. holder sorts first, so npm places its tok 3.0.2 before it reaches taker, whose slot then finds that copy: one tok, 3.0.2, although latest is 4.0.0. - $ ../../../bin/main.exe npm --offline --cache . --tree ./reuse-app/package.json | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . --tree ./reuse-app/package.json root reuse-app 1.0.0 packages (4): holder 1.0.0 @@ -369,7 +372,7 @@ depends on tok at * and on late, whose tok is ^3.0.0. npm places early's tok 4.0.0 before it reaches late, which gets a 3.0.2 of its own: a copy that only a later package requires is not there to be reused. - $ ../../../bin/main.exe npm --offline --cache . --tree ./reach-app/package.json | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . --tree ./reach-app/package.json root reach-app 1.0.0 packages (5): early 1.0.0 @@ -391,7 +394,7 @@ sits at the top, so npm reaches them by name. alpha brings mid, mid brings stream, and stream's tok ~3.0.0 is placed before npm reaches zeta, whose ^3.0.0 || ^4.0.0 then finds it: one tok, 3.0.2. - $ ../../../bin/main.exe npm --offline --cache . --tree ./hoist-app/package.json | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . --tree ./hoist-app/package.json root hoist-app 1.0.0 packages (6): alpha 1.0.0 @@ -415,7 +418,7 @@ nest-app depends on mark ^4 and on inner, whose mark ~3.0.0 is nested under it since 4.0.0 holds the top; outer's ^3.0.0 || ^4.0.0 looks up the top and keeps 4.0.0, although 3.0.2 is tagged latest. - $ ../../../bin/main.exe npm --offline --cache . --tree ./nest-app/package.json | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . --tree ./nest-app/package.json root nest-app 1.0.0 packages (5): inner 1.0.0 @@ -439,7 +442,7 @@ linter-plugin, whose own peer on linter is ^8.0.0 || ^9.0.0. npm replaces linter 10.0.0 with 9.0.0 there, the pick for linter-plugin's range; the driver keeps 10.0.0, the pick for resolver's *: - $ ../../../bin/main.exe npm --offline --cache . --tree ./resolver-app/package.json | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . --tree ./resolver-app/package.json root resolver-app 1.0.0 packages (3): linter 10.0.0 @@ -460,7 +463,7 @@ with 7.0.0, the pick for the syntax packages' range, since preset's range accepts it too: one compiler, 7.0.0, in both preset-app's directory and preset's. - $ ../../../bin/main.exe npm --offline --cache . --tree ./preset-app/package.json | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . --tree ./preset-app/package.json root preset-app 1.0.0 packages (5): compiler 7.0.0 @@ -513,7 +516,7 @@ under it, below sight-app's dial 2.0.0, and sight-right's sight-host peers on dial ^1.0.0; npm places sight-host and its peer under sight-right, where the lookup finds only 2.0.0, and fetches ^1.0.0's newest, 1.1.0: - $ ../../../bin/main.exe npm --offline --cache . --tree ./sight-app/package.json | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . --tree ./sight-app/package.json root sight-app 1.0.0 packages (7): dial 1.0.0 @@ -540,7 +543,7 @@ on tok ^3.0.0 and peers on tok ^4.0.0 and on theme ^1; theme is installed beside it as its peer, while tok is its own 3.0.2 and nothing asks for a 4.0.0. - $ ../../../bin/main.exe npm --offline --cache . --tree ./twin-app/package.json | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . --tree ./twin-app/package.json root twin-app 1.0.0 packages (4): theme 1.0.0 @@ -567,7 +570,7 @@ is deprecated, the key ties, and the newest is picked exactly as before. npm tests the field for truth, so an empty message deprecates nothing: depr-empty's latest 2.0.0, deprecated with "", is picked as any latest is. - $ ../../../bin/main.exe npm --offline --cache . --tree ./depr-app/package.json | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . --tree ./depr-app/package.json root depr-app 1.0.0 packages (5): depr 1.0.0 @@ -589,7 +592,7 @@ passes the engine test, the key ties, and only deprecated and semver decide: engine and engine-npm take their newest, and engine-depr takes the non-deprecated 2.0.0. - $ ../../../bin/main.exe npm --offline --cache . --tree ./engine-app/package.json | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . --tree ./engine-app/package.json root engine-app 1.0.0 packages (4): engine 2.0.0 @@ -611,7 +614,7 @@ the packument lists first. bmo lists 1.0.0+b first; bmd's 1.0.0+a is deprecated; bml tags 1.0.0+b latest though it lists 1.0.0+a first; bmp lists 1.0.0+1 before 1.0.0. npm 11.17 locks the same four: - $ ../../../bin/main.exe npm --offline --cache . --tree ./bmeta-app/package.json | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . --tree ./bmeta-app/package.json root bmeta-app 1.0.0 packages (5): bmd 1.0.0+b @@ -635,7 +638,7 @@ is current and unbuildable, and npm sorts on (not deprecated and engine ok) before engine ok before not deprecated -- the first key ties at false, so the engine key decides and the deprecated 1.0.0 wins. - $ ../../../bin/main.exe npm --offline --cache . --tree --node-version v24.19.0 --npm-version 11.17.0 ./engine-app/package.json | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . --tree --node-version v24.19.0 --npm-version 11.17.0 ./engine-app/package.json root engine-app 1.0.0 packages (4): engine 1.0.0 @@ -654,7 +657,7 @@ root asked for * and engine 2.0.0 is a version the host cannot run, yet naming it directly installs it, exactly as npm records an EBADENGINE package in a lockfile and complains at install time. - $ ../../../bin/main.exe npm --offline --cache . --node-version v24.19.0 engine@2.0.0 | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . --node-version v24.19.0 engine@2.0.0 root . packages (2): . @@ -670,7 +673,7 @@ take at 2.1.0. A root with no name is called ".", which no registry package can be. npm 11.17.0 answers the next four cases the same over these fixtures, and refuses plugin@next (ETARGET). - $ ../../../bin/main.exe npm --offline --cache . --tree ./proj/package.json | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . --tree ./proj/package.json root . packages (6): . @@ -699,7 +702,7 @@ With no package.json the project is empty and the specs are all of it. A bare name asks for *, a later spec for the same name replaces an earlier one, and a tag is the version the packument tags. - $ ../../../bin/main.exe npm --offline --cache . --tree plugin core@2.0.0 runtime runtime@1.0 util-lib@latest | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . --tree plugin core@2.0.0 runtime runtime@1.0 util-lib@latest root . packages (5): . @@ -718,7 +721,7 @@ one, and a tag is the version the packument tags. An alias spec names the directory and the package apart, so one package can be installed twice under two names. - $ ../../../bin/main.exe npm --offline --cache . --tree lodash@npm:util-lib@1.0.0 util-lib | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . --tree lodash@npm:util-lib@1.0.0 util-lib root . packages (3): . @@ -755,7 +758,7 @@ arborist loads a root's devDependencies after its dependencies, and the later entry of a name replaces the earlier, so devprod-app, which asks for devprod ^1 in dependencies and ^2 in devDependencies, gets 2.0.0: - $ ../../../bin/main.exe npm --offline --cache . ./devprod-app/package.json | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . ./devprod-app/package.json root devprod-app 1.0.0 packages (2): devprod 2.0.0 @@ -767,7 +770,7 @@ No range semver reads holds a '!', so npa takes !=1.0.0 for a tag name and refuses it (EINVALIDTAGNAME); the dependency is dropped and counted, as other specs no registry lookup resolves are: - $ ../../../bin/main.exe npm --offline --cache . ./bang-app/package.json | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . ./bang-app/package.json root bang-app 1.0.0 packages (1): bang-app 1.0.0 @@ -779,7 +782,7 @@ A dist-tag is resolved from the target's packument, to the tagged version exactly: devprod's old is 1.0.0. A tag the packument lacks matches nothing, so alpha, whose optional entry asks for nosuch, is abandoned: - $ ../../../bin/main.exe npm --offline --cache . ./tag-app/package.json | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . ./tag-app/package.json root tag-app 1.0.0 packages (2): devprod 1.0.0 @@ -796,7 +799,7 @@ util-lib 1.0.0. A peer or an override that is an alias puts another package under the name, which a peer's range and an override's cannot say, so both are dropped and counted: - $ ../../../bin/main.exe npm --offline --cache . ./spec-app/package.json | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . ./spec-app/package.json root spec-app 1.0.0 packages (4): devprod 1.0.0 @@ -811,7 +814,7 @@ The same on the command line, where the alias prefix is cased as npa allows and a spec that is neither a range nor a name a tag may have is refused: - $ ../../../bin/main.exe npm --offline --cache . kit@NPM:util-lib@1.0.0 digtag@beta2 | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . kit@NPM:util-lib@1.0.0 digtag@beta2 root . packages (3): . @@ -837,7 +840,7 @@ util-lib 1.2.0 stands. ovr-target-app overrides util-lib to 1.0.0: npm leaves the aliased dependency alone and installs util-lib 1.2.0, while here the override binds and 1.0.0 is installed. - $ ../../../bin/main.exe npm --offline --cache . --tree ./ovr-key-app/package.json | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . --tree ./ovr-key-app/package.json root ovr-key-app 1.0.0 packages (3): carrier 1.0.0 @@ -849,7 +852,7 @@ here the override binds and 1.0.0 is installed. encoded solution: 5 core nodes (6 lookups) loaded: 3 names, 4 versions, 0 packuments fetched - $ ../../../bin/main.exe npm --offline --cache . --tree ./ovr-target-app/package.json | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . --tree ./ovr-target-app/package.json root ovr-target-app 1.0.0 packages (3): carrier 1.0.0 @@ -869,7 +872,7 @@ alias-sat-app installs mark 3.0.2 at tok, as an alias, and depends on needer, whose tok is ^3.0.0. npm finds 3.0.2 at tok and installs no tok at all; here needer gets a tok 3.0.2 of its own. - $ ../../../bin/main.exe npm --offline --cache . --tree ./alias-sat-app/package.json | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . --tree ./alias-sat-app/package.json root alias-sat-app 1.0.0 packages (4): alias-sat-app 1.0.0 @@ -913,7 +916,7 @@ and listy's edge now resolves there: npm has listy on buf 5.1.2. Here listy keeps 5.2.1 and only rstream takes 5.1.2. Both answers meet every range, so the difference is one of preference, not validity. - $ ../../../bin/main.exe npm --offline --cache . --tree ./live-app/package.json | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . --tree ./live-app/package.json root live-app 1.0.0 packages (6): buf 5.1.2 @@ -939,7 +942,7 @@ bundles tok, and its tarball carries tok 3.0.1, a version the registry never published; npm takes that copy, nested in bundler, while here tok 3.0.2 is resolved. - $ ../../../bin/main.exe npm --offline --cache . --tree ./bundle-app/package.json | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . --tree ./bundle-app/package.json root bundle-app 1.0.0 packages (3): bundle-app 1.0.0 @@ -970,7 +973,7 @@ reaches a package is an output of resolution, not an input. ovr-path-app overrides tok to 4.0.0 under holder only; npm installs holder's tok at 4.0.0, while here holder's ^3.0.0 picks 3.0.2. - $ ../../../bin/main.exe npm --offline --cache . --tree ./ovr-path-app/package.json | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . --tree ./ovr-path-app/package.json root ovr-path-app 1.0.0 packages (3): holder 1.0.0 @@ -989,7 +992,7 @@ peers on tok ^4.0.0. perch holds no tok, so here the peer forces nothing and the only tok is the top's 3.0.2. npm checks whatever copy lurker's lookup finds, refuses 3.0.2, and nests lurker and a tok 4.0.0 under perch. - $ ../../../bin/main.exe npm --offline --cache . --tree ./perch-app/package.json | sed -E '/^(parse|solve) [0-9.]+s$/d' + $ untimed ../../../bin/main.exe npm --offline --cache . --tree ./perch-app/package.json root perch-app 1.0.0 packages (4): lurker 1.0.0 diff --git a/test/frontends/opam.t/run.t b/test/frontends/opam.t/run.t index 51f1521..c44ac03 100644 --- a/test/frontends/opam.t/run.t +++ b/test/frontends/opam.t/run.t @@ -1,6 +1,7 @@ -untimed drops the timings from pac's output and keeps its exit status: +untimed (../untimed.sh) drops the timings from pac's output and keeps its +exit status: - $ untimed() { "$@" > out 2>&1; s=$?; sed -E '/^(parse|solve) [0-9.]+s$/d' out; return $s; } + $ . ../untimed.sh $ untimed ../../../bin/main.exe opam . app packages (2): diff --git a/test/frontends/untimed.sh b/test/frontends/untimed.sh new file mode 100644 index 0000000..be71503 --- /dev/null +++ b/test/frontends/untimed.sh @@ -0,0 +1,3 @@ +# the output less its timing lines, which vary from run to run, and the +# exit status, which a pipe into sed would lose +untimed() { "$@" > out 2>&1; s=$?; sed -E '/^(parse|solve) [0-9.]+s$/d' out; return $s; }