Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions internals/distcheck/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ tooling, so one tested home matters more than language purity of the harness.
`import dirsql`. Nothing is staged: since #738 the wheel's extension module
carries the CLI and the console script calls it in-process.
- **`node`** -- packs the main `dirsql` package and a reconstructed host
`@dirsql/cli-<slug>` sub-package, `npm install`s both into a fresh dir, and
`@dirsql/lib-<slug>` sub-package, `npm install`s both into a fresh dir, and
runs `node_modules/.bin/dirsql --version`, cross-checking the installed
sub-package layout.
sub-package layout. Nothing separate is staged for the CLI: since #739 the
napi addon carries it and the launcher calls it in-process.

**Caveat (host triple only):** each flow tests the host triple/interpreter.
Cross-target coverage lives in the release pipeline's install matrix (one runner
Expand Down
19 changes: 14 additions & 5 deletions internals/distcheck/src/distcheck/node_flow/gate.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
the per-package `build.test.ts`).

build -> pack -> install -> run: pack the main `dirsql` package and a
reconstructed host `@dirsql/cli-<slug>` sub-package the way the release pipeline
reconstructed host `@dirsql/lib-<slug>` sub-package the way the release pipeline
would, `npm install` both into a fresh dir, and run
`node_modules/.bin/dirsql --version`. No mocks -- exactly what `npx dirsql` does
for an end user.
Expand All @@ -11,8 +11,9 @@
- Tests only the host triple. Cross-triple coverage lives in the release matrix
(one runner per target).
- The per-platform `package.json` shape is reconstructed here (it is normally
generated by the release tool), in the shape `src/cli/resolve-binary.ts`
consumes, so the real launcher resolution path is still exercised.
generated by the release tool), in the shape `loadNativeCore()` consumes, so
the real addon resolution path -- which since #739 serves the CLI too -- is
still exercised.

Effects funnel through an injected `runner` (subprocess.run) and `fs`
(FileSystem); the detected host `Platform` is passed in so each stage is
Expand Down Expand Up @@ -56,6 +57,15 @@ def select_tarball(names, prefix: str, exclude: Optional[str] = None) -> str:
return only


def staged_addon_path(ts_pkg: str, host: Platform) -> str:
"""Where `pnpm build` stages the host addon -- the flow's one prerequisite.

Exported so other callers guard on the path `run` actually requires,
rather than restating the staging layout in a second place.
"""
return os.path.join(ts_pkg, "build", host.slug, host.addon_name)


def run(
ts_pkg: str,
host: Platform,
Expand All @@ -65,8 +75,7 @@ def run(
) -> int:
# pnpm build (napi:build + tsc + stage:platform) is a CI prerequisite; the
# staged host addon is its output. Sanity-check rather than rebuild.
staged_dir = os.path.join(ts_pkg, "build", host.slug)
staged_addon = os.path.join(staged_dir, host.addon_name)
staged_addon = staged_addon_path(ts_pkg, host)
if not fs.exists(staged_addon):
raise DistcheckError(
f"prerequisite missing: {staged_addon}. "
Expand Down
8 changes: 8 additions & 0 deletions internals/distcheck/src/distcheck/node_flow/gate_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
_require_zero,
run,
select_tarball,
staged_addon_path,
)


Expand Down Expand Up @@ -143,10 +144,17 @@ def test_run_success_executes_the_full_sequence():
]


def test_staged_addon_path_builds_the_pnpm_build_output_path():
assert staged_addon_path("/ts", _HOST) == _STAGED


def test_run_missing_staged_binary_raises_prereq():
fs = _fs(exists=lambda p: False)
with pytest.raises(DistcheckError, match="prerequisite missing"):
run("/ts", _HOST, runner=mock.Mock(), fs=fs)
# The prerequisite `run` demands IS `staged_addon_path`'s output -- the
# contract other callers guard on.
fs.exists.assert_called_once_with(staged_addon_path("/ts", _HOST))
fs.copy.assert_not_called()


Expand Down
11 changes: 4 additions & 7 deletions internals/distcheck/tests/integration/node_flow_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Runs `gate.run` with its default `subprocess.run` / real `FileSystem` -- the
build -> pack -> install -> run behavior the old per-package packaging
suite exercised. Skips when the build prerequisites (the staged host CLI binary
suite exercised. Skips when the build prerequisites (the staged host addon
from `pnpm build`, `npm`/`pnpm`) are absent, since the flow's actual CI
execution is the `dirsql-distcheck node` job, which builds them first.
"""
Expand All @@ -15,7 +15,7 @@

import pytest

from distcheck.node_flow.gate import run
from distcheck.node_flow.gate import run, staged_addon_path
from distcheck.node_flow.platforms import detect_host

_REPO = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "..", ".."))
Expand All @@ -24,11 +24,8 @@

def test_npm_installed_cli_packs_installs_and_runs():
host = detect_host(sys.platform, platform.machine())
staged = os.path.join(
_TS, "build", f"bundled-cli-{host.slug}", host.bin_name
)
if not os.path.exists(staged):
pytest.skip("staged CLI binary absent (pnpm build in packages/ts)")
if not os.path.exists(staged_addon_path(_TS, host)):
pytest.skip("staged addon absent (pnpm build in packages/ts)")
if shutil.which("npm") is None or shutil.which("pnpm") is None:
pytest.skip("npm/pnpm not on PATH")

Expand Down