Commit Graph

14 Commits

Author SHA1 Message Date
Zoltan Kochan
d2cdb8de65 test(git-fetcher): end-to-end shallow-fetch argv assertion via PATH-shim (#436 §E follow-up) (#487)
Ports the last open §E test — upstream's [`fetching/git-fetcher/test/index.ts:183`](https://github.com/pnpm/pnpm/blob/94240bc046/fetching/git-fetcher/test/index.ts#L183) `still able to shallow fetch for allowed hosts`, which jest-mocks `execa` to spy on the `git` argv.

Pacquet can't intercept `Command::new("git")` without touching production code, so the test uses a `/bin/sh` shim on `PATH`:

1. Writes `<tempdir>/shim/git`: a tiny shell script that tab-logs each invocation to a file and fakes `rev-parse HEAD` so the fetcher's commit-match check passes.
2. Prepends the shim dir to `PATH` for the test body via `unsafe { std::env::set_var(...) }`. Edition 2024 requires `unsafe`; the project's `cargo nextest` runner isolates each test in its own process so no sibling can race the modified env. PATH is restored before assertions.
3. Parses the log and asserts the shallow sequence: `git init` → `git remote add origin <url>` → `git fetch --depth 1 origin <commit>`, with `git clone` absent.

`fetcher_clones_when_host_not_in_shallow_list` is the mirror — same shim, empty `git_shallow_hosts`, asserts `git clone <url> <dir>` appears and `init` / `fetch` don't. Together the two tests pin the gate's polarity end-to-end. The existing `should_use_shallow_matches_known_host` unit test only covers the predicate cross-platform; the new tests add Unix end-to-end argv coverage.

Unix-only via `#[cfg(unix)]`. A Windows mirror would need a `.cmd` shim and a different launcher; the predicate-level test still covers Windows.
2026-05-13 23:24:40 +02:00
Anthony Shew
1d5f8b5dca test(modules-yaml): set up parity tests (#309)
## Summary
- Add a [Stage 1](https://github.com/pnpm/pacquet/issues/299) test-porting map for TypeScript parity work.
- Add a `modules-yaml` crate.
- Add the first five 1:1 known-failure ports from pnpm's modules-yaml tests, each pinned to its upstream source permalink.
2026-04-28 16:19:32 +02:00
Khải
51571b78c5 chore(rust): edition 2024 (#322)
* chore(workspace): switch to Rust edition 2024

Bump `edition` to 2024 in the workspace package metadata. The toolchain
is already pinned at 1.95.0 (latest stable as of 2026-04-14), which has
2024 edition support. Migration touches:

- collapse `if let { if let { … } }` chains into `let … && let …` to
  satisfy the new `clippy::collapsible_if` shape under edition 2024
  (let-chains are stable in 2024).
- wrap `env::set_var` / `env::remove_var` calls in `unsafe { … }`
  blocks now that they require an `unsafe` context. The test-only
  `EnvGuard` already serializes env mutation against the rest of the
  test process via a process-wide `Mutex`, so the safety condition
  ("no other thread accesses the env concurrently") still holds; the
  unsafe markers just make that contract explicit.
- bind a `Client` to a named local in `AutoMockInstance::load_or_init`
  so it outlives the borrow inside `MockInstanceOptions`. Edition 2024
  shortens temporary lifetimes in `let` initializers, so the previous
  `&Client::new()` inside a struct literal would have dangled.
- replace `prefetched.get(&index_key).is_none()` with
  `!prefetched.contains_key(&index_key)` per
  `clippy::unnecessary_get_then_check`.

The remaining diff is `cargo fmt` reflowing imports under the 2024
style edition (alphabetical ordering inside grouped `use { … }`
blocks).

* fix(npmrc): collapse Windows get_drive_letter `if let` chain

The `clippy::collapsible_if` lint also fires on the Windows-only
`get_drive_letter` helper, which was missed by the Linux/macOS clippy
pass during the edition 2024 migration. Apply the same `if let … &&
let …` collapse the lint suggested.

* style(lockfile): re-sort imports under 2024 style edition

Files added by `refactor: replace serde_yaml with serde_saphyr` (#320)
on main use the 2021 import-name ordering (`{serialize_yaml, Lockfile}`,
`{ser, ..., SerializerOptions}`). The 2024 style edition sorts use names
alphabetically, so the PR's merge ref tripped `cargo fmt --all -- --check`
once main caught up.

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-27 13:41:48 +02:00
Zoltan Kochan
0b0abf8189 feat!(store): migrate from v3 JSON index to v11 SQLite+msgpack (#244) (#247)
* feat!(store): migrate from v3 JSON index to v11 SQLite+msgpack layout

Pacquet now writes the same on-disk store that pnpm v11 uses, so running
pacquet and pnpm on the same machine can share the tarball cache instead
of maintaining parallel stores. Closes half of #244.

- **Layout:** \`<store>/v11/files/XX/<hex-remainder>[-exec]\` for
  content-addressed blobs + \`<store>/v11/index.db\` for the per-package
  file index. The legacy \`v3/files/XX/<hex>-index.json\` JSON layout is
  gone (we don't need backward compat — pacquet is pre-1.0).
- **SQLite schema / PRAGMAs:** byte-identical to pnpm's
  \`store/index/src/index.ts\` — \`package_index (key TEXT PRIMARY KEY,
  data BLOB NOT NULL) WITHOUT ROWID\` with WAL journal, 5s busy_timeout,
  512 MB mmap, 32 MB page cache, temp_store=MEMORY,
  wal_autocheckpoint=10000. Two concurrent pacquet tasks (or a pacquet
  + pnpm pair) contend correctly via SQLite's own locking.
- **Value encoding:** msgpack via \`rmp-serde::to_vec_named\` so structs
  are serialized with named fields, matching pnpm's msgpackr record
  encoding. \`PackageFilesIndex\` and \`CafsFileInfo\` types mirror pnpm's
  \`@pnpm/store.cafs\` shape field-for-field (including the hex \`digest\`
  rather than pacquet's old SSRI \`integrity\` string).
- **Key format:** \`"{integrity}\\t{pkg_id}"\` via \`store_index_key()\`,
  same as pnpm's \`storeIndexKey\`. \`pkg_id\` is \`"{name}@{version}"\` —
  pulled from \`PkgNameVerPeer::without_peer()\` on the frozen-lockfile
  path and assembled from \`PackageVersion\` on the registry path.

Breaking API changes inside the workspace:
- \`pacquet-store-dir\` loses the v3 JSON types (\`PackageFilesIndex\`,
  \`PackageFileInfo\`, \`WriteIndexFileError\`) and \`StoreDir::v3()\` /
  \`::write_index_file()\`. In their place: \`StoreIndex\`, \`StoreIndexError\`,
  the pnpm-shape \`PackageFilesIndex\` + \`CafsFileInfo\`, and
  \`store_index_key()\`. Unit-tested with 9 new round-trip / re-open /
  key-format tests.
- \`DownloadTarballToStore\` gains a \`package_id\` field. All three
  callers (two in \`pacquet-package-manager\`, one in the micro-benchmark)
  pass \`"{name}@{version}"\`.
- \`pacquet-testing-utils::add_mocked_registry\` now also writes
  \`pnpm-workspace.yaml\` with \`storeDir\` / \`cacheDir\` so pnpm 11 (which
  moved that config out of \`.npmrc\`) respects the test's store
  override.
- \`crates/cli/tests/_utils.rs::index_file_contents\` now walks
  \`StoreIndex::keys()\` and returns \`BTreeMap<sqlite_key,
  BTreeMap<filename, CafsFileInfo>>\`. The insta snapshots will need
  re-accept once the test run against the new mock layout settles.
- Dropped the \`#[ignore]\` on
  \`pnpm_compatibility::{same_file_structure, same_index_file_contents}\`
  — the v11 cutover is the prerequisite they were waiting on. The
  install-path snapshots in \`install.rs\` will likely need a re-accept
  through \`cargo insta test --accept\`; running them requires
  \`just registry-mock launch\` and is tracked at the top of
  \`crates/cli/tests/install.rs\`.

Dependencies added at the workspace level: \`rusqlite = "0.38"\` (with
the \`bundled\` feature so we don't need a system libsqlite3) and
\`rmp-serde = "1.3\"\`. Dropped the unused \`base64\` dep from \`tarball\`.

Verified end-to-end: \`pnpm install --lockfile-only\` against
\`@pnpm/registry-mock\` followed by \`pacquet install --frozen-lockfile\`
produces \`store-dir/v11/files/XX/…\` + \`store-dir/v11/index.db\` with
50 rows whose keys match pnpm's \`{integrity}\\t{pkgId}\` format
(verified via sqlite3 CLI against the pacquet-written db).

Follow-ups (tracked in #244 and this PR's description):
- Teach pacquet's config loader to read \`pnpm-workspace.yaml\` in
  addition to \`.npmrc\` so \`storeDir\` / \`cacheDir\` / \`registry\`
  overrides resolve without requiring the .npmrc mirror.
- Read the index at install-time to skip re-fetching already-cached
  tarballs.
- Decode msgpackr \`useRecords\` entries so pacquet can read back
  records that pnpm itself wrote (pnpm reads pacquet's named-field
  writes fine today; the reverse direction is the missing piece).

* chore(deny): allow Zlib license for foldhash (transitive via rusqlite)

rusqlite pulls in foldhash 0.2, which is Zlib-licensed. Zlib is
OSI-approved and widely accepted; add it to the allow list.

* test: re-accept v11 store snapshots + scope pnpm_compatibility tests

Aftershocks from the v11 store migration:

- Three insta snapshots in crates/cli/tests/snapshots/install__*.snap
  referenced the old \`v3/files/.../*-index.json\` paths and had to be
  re-accepted via \`cargo insta test --accept\` to reflect the new
  \`v11/files/XX/<hex>[-exec]\` + \`v11/index.db\` layout. Inner
  file integrities are unchanged; only the store-dir path prefix
  differs.

- \`pnpm_compatibility::same_file_structure\` now filters out three
  pnpm-11-specific artifacts that pacquet has no equivalent for, but
  which don't affect the shared-CAFS invariant the test is there to
  verify:
    * \`v11/projects/<hash>\` — pnpm-11 per-project metadata.
    * \`v11/links/<name>/<version>/<hash>/node_modules/...\` — pnpm
      11's hoisted-symlinks layout; pacquet uses its own
      \`.pnpm/\`-based virtual store.
    * \`v11/index.db-{wal,shm}\` — SQLite WAL sidecars whose presence
      at compare-time depends on whether the checkpoint ran.
  With that filter the two tools' CAFS file listings match byte-for-
  byte.

- \`pnpm_compatibility::same_index_file_contents\` goes back under
  \`#[ignore]\` with an updated reason. Pacquet-written \`index.db\`
  values round-trip fine (we serialize via \`rmp-serde::to_vec_named\`,
  string-keyed maps), but pnpm writes with msgpackr's \`useRecords:
  true\` extension-typed records that rmp-serde can't decode. Handling
  those is the last piece of #244 (msgpackr-record decoding for the
  read side) and will be addressed after this PR lands.

* review: address Copilot feedback on the v11 store migration

- \`TarballError::WriteStoreIndex\` display message was still "Failed to
  write tarball index" (a leftover from the per-package JSON era).
  Rephrased to "Failed to write store index (SQLite index)".
- \`entry.header().size().unwrap_or(0)\` silently turned tar header
  parse errors into 0-byte entries in the index. Propagate the error
  via \`TarballError::ReadTarballEntries\` instead.
- Open + PRAGMA + \`INSERT\` on the SQLite index are blocking (and can
  stall up to \`busy_timeout=5000\` ms under contention). Moved the
  write step into \`tokio::task::spawn_blocking\` so it runs on the
  blocking pool instead of the tokio reactor. The tarball-extraction
  loop (which holds a \`!Send\` \`tar::Archive\`) is now scoped into a
  sub-block so it's dropped before the new \`await\`.
- Added \`StoreIndex::open_readonly\` / \`open_readonly_in\` that use
  \`SQLITE_OPEN_READ_ONLY\` and skip the schema-creation PRAGMAs.
  \`crates/cli/tests/_utils.rs::index_file_contents\` now uses it so
  the snapshot helper doesn't mutate the store or create WAL / SHM
  sidecar files during what is supposed to be a read.
- Clarified the \`StoreIndex\` module-level doc comment: the DB lives
  at \`<store-root>/v11/index.db\` when opened via \`open_in\`, not at
  \`<store_dir>/index.db\` as the old wording suggested.
2026-04-23 19:06:14 +02:00
Zoltan Kochan
aef67087e9 feat!: pnpm lockfile v9 support + install error propagation + Rust 1.95 (#243)
* refactor(install): propagate errors through the Install stack

Replace the three `unimplemented!()` panics in the install dispatcher
with proper miette diagnostics, and thread `Result` propagation through
`Install`, `InstallWithoutLockfile`, `InstallFrozenLockfile`, and
`CreateVirtualStore`.

New `InstallError::NoLockfile` (code `pacquet_package_manager::no_lockfile`)
is returned when `--frozen-lockfile` is requested but no `pnpm-lock.yaml`
exists, mirroring pnpm's `ERR_PNPM_NO_LOCKFILE`. The two remaining
writable-lockfile paths surface as `InstallError::UnsupportedLockfileMode`
until lockfile writing lands.

Downstream `.unwrap()`s on `InstallPackageFromRegistryError` and
`InstallPackageBySnapshotError` now become `?`, and the `join_all` calls
switch to `try_join_all` to fail fast.

* feat(lockfile): add Lockfile::save_to_path and save_to_current_dir

Introduces the write side of the lockfile API paired with the existing
`load_lockfile` module. Emits YAML via `serde_yaml::to_string` and
propagates serde/io failures through a new `SaveLockfileError`
(codes `pacquet_lockfile::serialize_yaml`, `pacquet_lockfile::write_file`,
`pacquet_lockfile::current_dir`).

The output is semantically equivalent to the input (parse → save → reparse
yields an equal `Lockfile`), but is NOT yet byte-identical with pnpm's
`sortLockfileKeys`-based output — matching the exact key order and YAML
style pnpm produces is a separate piece and will come with the install
path that consumes this API.

* feat(package-manager): add build_snapshot helpers for PackageVersion -> PackageSnapshot

Introduces `registry_dependency_path` and `build_package_snapshot` in a
new `build_snapshot` module. Given a resolved `PackageVersion` plus an
injected map of resolved sub-dependencies and dev/optional flags, they
produce the `(DependencyPath, PackageSnapshot)` pair that can be dropped
into a `pnpm-lock.yaml`'s `packages` map.

The helpers are pure and unit-tested with synthetic fixtures — wiring
them into `InstallWithoutLockfile` to collect live resolution metadata
and construct the full `Lockfile` is the next step.

Errors propagate via `BuildSnapshotError` (`missing_integrity`,
`parse_name`) rather than panicking when input is malformed.

* feat!(lockfile): replace v6 types with v9 (packages + snapshots + importers)

pnpm v11 writes lockfile v9 exclusively. Pacquet's existing v6 types
cannot read these files. Per-session agreement, no backward
compatibility with v6 is kept.

Type rewrite in `pacquet-lockfile`:
- `Lockfile` now carries `importers: HashMap<String, ProjectSnapshot>`
  (with `Lockfile::ROOT_IMPORTER_KEY = "."`) instead of a flattened
  `RootProjectSnapshot`, plus separate `packages: HashMap<PackageKey,
  PackageMetadata>` and `snapshots: HashMap<PackageKey, SnapshotEntry>`
  maps keyed by the v9 `name@version[(peers)]` specifier (no leading
  slash).
- `PackageMetadata` (new) holds per-version data (resolution, engines,
  cpu/os/libc, deprecated, hasBin, peer metadata). `SnapshotEntry`
  (new) holds per-instance data (dependencies, optional_dependencies,
  transitive_peer_dependencies, id, patched).
- `PkgNameVerPeer::without_peer` strips the peer suffix so consumers
  can look up a snapshot entry's metadata in the `packages:` map.
- Deleted: `dependency_path.rs`, `multi_project_snapshot.rs`,
  `package_snapshot.rs`, `package_snapshot_dependency.rs`,
  `root_project_snapshot.rs`.
- `LockfileVersion<9>` with the v6 compat test swapped for v9.

Consumer updates in `pacquet-package-manager`:
- `InstallFrozenLockfile` now takes `importers`, `packages`, and
  `snapshots` separately.
- `CreateVirtualStore` iterates `snapshots` and resolves each
  snapshot's metadata via `PackageKey::without_peer()`, returning
  `MissingPackageMetadata` if the lockfile is inconsistent.
- `InstallPackageBySnapshot` takes `(package_key, metadata, snapshot)`
  and reads resolution from `PackageMetadata`.
- `CreateVirtualDirBySnapshot` derives the virtual store dir from the
  `PackageKey` and reads dependency wiring from the `SnapshotEntry`.
- `SymlinkDirectDependencies` looks up the root project via
  `importers[Lockfile::ROOT_IMPORTER_KEY]` instead of pattern-matching
  `RootProjectSnapshot::Single`.
- `create_symlink_layout` takes `HashMap<PkgName, PkgVerPeer>` (the v9
  snapshot deps shape) instead of the legacy enum.
- `build_snapshot` returns `BuiltSnapshot { package_key, metadata,
  snapshot }` matching the v9 decomposition.

Fixture updates:
- `BIG_LOCKFILE` regenerated as v9 via pnpm v11.
- Save-lockfile round-trip fixture rewritten in v9 shape.
- Save-lockfile error fixture uses `lockfileVersion: '9.0'`.

Verified end-to-end: `pnpm install --lockfile-only` generates a v9
lockfile against `@pnpm/registry-mock`, then `pacquet install
--frozen-lockfile` populates node_modules from that lockfile (50
packages, symlinks wired).

Benchmark on the pacquet fixture manifest against the registry mock
(hyperfine, 10 runs + 2 warmup):
- pacquet:   487.9 ms ± 106.6 ms  (range 343-656 ms)
- pnpm@11:   739.6 ms ±   9.1 ms  (range 725-751 ms)
- pacquet is 1.52x faster; worst-case pacquet still beats best-case pnpm.

* style(install): apply cargo fmt

* chore(deny): rewrite deny.toml for cargo-deny 0.19 schema

The old template predated cargo-deny 0.14. The schema has since moved
the graph/output keys under dedicated sections and changed advisory
level fields. Rewritten to follow the 0.19 shape.

Also adds a scoped ignore list for the RUSTSEC advisories that exist
in the already-pinned transitive deps (bytes, h2, idna, mio, openssl,
tar, tokio, tracing-subscriber) — resolving those requires bumping the
1.73.0 toolchain and a round of coordinated dep updates that is out of
scope for this PR.

* chore(toolchain): bump rust-toolchain.toml to 1.95.0 + fix CI fallout

Bumps the pinned Rust channel from 1.73.0 to 1.95.0 and addresses the
consequences:

- `tasks/registry-mock/src/registry_anchor.rs`: migrate off the
  `advisory-lock` crate to Rust 1.89+'s stable `std::fs::File::{lock,
  try_lock}` (the crate's trait methods now collide with std's). Drop
  the workspace dep.
- New rustc/clippy lints under 1.95:
  - `mismatched_lifetime_syntaxes` → add explicit `'_` to
    `StoreDir::display`.
  - `clippy::map_clone` → `.cloned()` in `PackageManifest::bundle_dependencies`.
  - `clippy::manual_pattern_char_comparison` → array pattern in
    `PkgVerPeer` parser.
  - `clippy::suspicious_open_options` → add `.truncate(false)` to the
    persistent lock file in `GuardFile::path`.
  - `clippy::useless_into_iter_in_iterator_adapter` →
    `InstallWithoutLockfile::run` dependencies call.
  - `clippy::manual_unwrap_or` → collapse `if let Some` match in the
    `pacquet start` fallback.
- `crates/cli/tests/install.rs`: move `BIG_LOCKFILE` / `BIG_MANIFEST` /
  `OpenOptions` / `io::Write` imports behind the same
  `cfg(not(macos|windows))` gate as their one consumer so they aren't
  flagged as unused on macOS.

Also unblocks the Micro-Benchmark / Code Coverage / release-to-npm
workflows: bump `actions/upload-artifact@v3` → `@v4` (v3 is now
hard-rejected by GitHub Actions).

`cargo build --workspace`, `cargo clippy --locked --workspace
--all-targets -- --deny warnings`, `cargo fmt --all -- --check`, and
`cargo deny check` all pass locally on 1.95.

* chore(ci): bump actions/download-artifact to v4 (v3 is hard-rejected)

* test(cli): disable flaky big-lockfile test on all CI platforms

The test drives the mocked verdaccio with hundreds of concurrent tarball
fetches and reliably trips a connection error on every hosted-runner OS:
ConnectionAborted on Windows, ConnectionReset on macOS, and now
ConnectionClosed on Ubuntu (the regenerated v9 BIG_LOCKFILE has more
packages, so Ubuntu started hitting the same class of issue the other
platforms already gated out).

Align the cfg gate to exclude all three and document the manual run
recipe. The BIG_LOCKFILE / BIG_MANIFEST / OpenOptions / io::Write
imports follow the same gate.

* test(integrated-benchmark): regenerate lockfile fixture as v9

The fixture was v6 and consequently unparseable by HEAD after the v9
rewrite, which failed the Integrated-Benchmark CI run in Benchmark 1
(pacquet@HEAD) before it could even start hyperfine.

With the fixture at v9 the benchmark can at least evaluate pacquet@HEAD
standalone. The HEAD-vs-main hyperfine comparison that this workflow is
designed for is intrinsically broken by this PR (main still speaks v6
only, so it cannot read a v9 fixture); that failure is an expected
consequence of the breaking format change and will resolve once this
PR lands on main.

* review: replace remaining panics/silent-failures with proper diagnostics

Addresses Copilot review feedback on the install path. Every code path
that previously used `panic!` / `expect` / silent `return` now either
surfaces a structured error or — in the test-gating case — uses
`#[ignore]` so the test remains runnable locally.

- `InstallPackageBySnapshotError`: new `MissingTarballIntegrity` and
  `UnsupportedResolution` variants; `install_package_by_snapshot` no
  longer panics when a tarball resolution lacks an integrity field or
  when the lockfile references Directory/Git resolutions that pacquet
  does not yet handle.
- `CreateVirtualStoreError`: new `MissingPackagesSection` variant for
  the case where a lockfile has `snapshots:` but no `packages:`. The
  dispatcher no longer panics in that case.
- `SymlinkDirectDependenciesError`: new `MissingRootImporter` variant.
  A lockfile with no `importers."."` entry now produces a clear
  diagnostic instead of silently producing an incomplete install.
  `InstallFrozenLockfile` gains a transparent variant that wraps it.
- `BuildSnapshotError::ParseVersion`: `registry_package_key` now
  propagates `ParsePkgVerPeerError` instead of `.expect`-ing that
  `node_semver::Version::to_string` always yields a valid `PkgVerPeer`.
  The two grammars agree today but the assumption is no longer encoded
  as a panic.
- `frozen_lockfile_should_be_able_to_handle_big_lockfile`: replace the
  overly-broad `cfg(not(any(windows, macos, linux)))` gate with
  `#[ignore = "flaky on CI…"]`. The test is now runnable locally via
  `cargo test -- --ignored` per the updated comment.
- Drive-by: drop `.write(true)` next to `.append(true)` flagged by
  `clippy::ineffective_open_options` after the import un-gating above.

Manual verification: `pnpm install --lockfile-only` against
`@pnpm/registry-mock` followed by `pacquet install --frozen-lockfile`
still produces the expected `node_modules` + `.pnpm/` layout.
2026-04-23 16:09:44 +02:00
Khải
6ae9f08a19 test: big lockfile (#213)
* test: big lockfile

* fix(test): ignore failed platforms
2023-11-22 02:07:34 +02:00
Khải
7ad33aa65b test: registry-mock (#198)
* test: fix snapshot

* test: filter out index files temporarily

* chore: install registry-mock

* chore(just): add pnpm to test

* feat: create registry-mock crate

* feat(registry-mock): expose get_or_init instead

* refactor: local static

* feat(testing-utils): add_mocked_registry

* refactor: rename new to init

* fix: enable_all

* refactor: use

* feat: add ending /

* fix: must be "localhost"

* feat(registry-mock): use portpicker

* feat(registry-mock): share a single instance

* feat(testing-utils): stop skipping index files

* test(cli/install): use registry-mock

* fix: forgot to save

* fix: forgot increment

* fix: used to wrong syntax

* feat(registry-mock): use advisory-lock

* fix: save anchor before early exit

* fix: drop before delete

* tmp: stored

* refactor: remove unused import

* fix: truncate the file

* feat: use try_lock

* feat(registry-mock): separate lock from anchor

* refactor: use RAII pattern

* fix(registry-mock): user_count

* refactor: rename user_count to ref_count

* fix: kill groups

* fix(registry-mock): ref_count

* chore(git): revert broken fix

This reverts commit 8c0ba7bafd7670dd6580a142ccd7dea5809ed782.

* fix(registry-mock): use sysinfo to kill

* fix(registry-mock): kill algorithm

* feat(registry-mock): recurse regardless

* feat(registry-mock): use reverse recursion instead

* refactor: reduce complexity

* refactor: remove unnecessary mod declarations

* refactor: marks some struct as must_use

* test(cli/add): use registry-mock

* test(pnpm-compatibility): use registry-mock

* refactor: remove unused items

* docs: correction

* chore(license): allow MPL-2.0

* chore(license): allow Unlicense

* fix(registry-mock): failure on few threads

* chore: move pnpm install to just

* ci: cache pnpm

* fix(test): kill leftovers

* fix(test): allow delete to fail

* fix(ci): Install just

* fix(test): don't kill leftovers

This reverts commit ef78d8c54cee691d93fa8e5c169141a0098047f2.

* refactor: move some types to their own mods

* refactor: move port_to_url

* refactor: make listen lazy

* refactor: rename `listen` to `url`

* refactor: use qualified path

* refactor: store port as u16

* feat(registry-mock): PreparedRegistryInfo

* refactor: remove unnecessary async

* refactor: move init code

* refactor: define lib

* feat(registry-mock): bin

* refactor: call just test

* ci: prepare a server

* feat(registry-mock): unique prepared

* docs(registry-mock): cli

* feat(registry-mock/cli): locations of log files

* docs(mocked-registry): important items

* docs(registry-mock): ignore bin

* style: taplo fmt

* docs(readme): instruction to run test

* refactor: move registry-mock to tasks

* ci(codecov): fix

* feat(registry-mock): bump max_retries
2023-11-17 15:26:13 +02:00
Khải
b0d5549210 feat(benchmark): allow overriding lockfile (#196)
* feat(benchmark): allow overriding lockfile

* test: fix snapshot

* test: fix snapshot

* test: filter out index files temporarily

* test: fix snapshot
2023-11-15 01:53:26 +02:00
Khải
2848e5a65a refactor: rewrite the bin functions into a struct (#176)
* refactor: convert 2 functions into a struct

* refactor: symmetry

* refactor: rename a constructor

* docs: consistent grammar
2023-11-03 02:44:59 +02:00
Khải
8f6e09ed36 refactor: functional style for testing_utils::fs (#173) 2023-11-03 02:37:22 +02:00
Khải
222bc2ce1b feat: store dir structure compatible with pnpm (#166)
Resolves https://github.com/pnpm/pacquet/issues/165

**Other changes:**
* A new crate named `pacquet-store-dir` has been created.
* The field `store-dir` in `Npmrc` has been changed from `PathBuf` to `StoreDir`.
* The function `write_sync` in `pacquet-cafs` has been replaced by 2 functions (8f98e730c1).
* The `pacquet-cafs` crate has been merged into `pacquet-store-dir` (db673efdc9).
* The `pacquet-tarball` crate now also writes index files (3b6e68a48b0711a2666bbe4964b9fd485a9842d3..8f98e730c1c35e2371b1d5ebd7f9e3f86b99104e).
* The command `pacquet prune` now panics on `todo!()` for being incomplete (c8526d0d33).
2023-11-02 18:04:21 +02:00
Khải
36fee01f64 test: define custom .npmrc and snapshot the store (#169) 2023-10-31 22:51:32 +02:00
Khải
05a0cd07cc ci: add taplo (#163)
* ci: add taplo

* style: use taplo to format

* style: allow only 1 blank line

* ci: fix binary name
2023-10-28 20:19:05 +03:00
Khải
0db25f85a2 refactor: re-organize code (#143)
## Summary

* Move code that handles package managing to its own crate named `pacquet_package_manager`.
  * Convert functions with multiple arguments into structs.
* Make `pacquet add` reuses the algorithm from `pacquet install`.
  * Achieved by having `pacquet add` creates an in-memory `package.json` and pass it to the `Install` subroutine.
* Convert the error-prone tests in `crates/cli` into proper integration tests that invoke the `pacquet` binary.
  * Tests become shorter and more readable.
  * Solve race condition issues with `cargo test`.
* All code with `set_current_dir` have been replaced by either integration tests or dependency injection.
  * Solve race condition issues with `cargo test`.
* `thiserror` has been completely removed. `derive_more` is used in its stead.
  * `thiserror` cannot handle generic trait bound.
  * `derive_more` is already used to generate custom string types in the lockfile.
  * one less macro crate leads to slightly faster compile time.
* `pacquet_package_json::PackageJson` has been renamed to `pacquet_package_manifest::PackageManifest`.
* Other minor changes.
2023-10-26 22:34:09 +03:00