Skip to content

nvx-rs slimming 1.1.2: one Cargo workspace, and the new crates' empty shells #1092

Closed as not planned

Description

Parent: #1077, in #1076. Needs: #1091. Unblocks: #1093, #1095, #1096, #1097, #1106, #1113, #1115, #1118, #1127.

Goal. The repository is one Cargo workspace, with nvx-rs and empty shells for nvx-sys, nvx-control, nvx-guest-tools, nvx-init, nvx-cli, nvx-testing and nvx-api-tests. nvx-sys declares the dependencies of its first moves; nvx-control has its host and guest features; and the shells declare their final path dependencies as the target crates become available, except that nvx-api-tests stays dependency-free until SL5.1a in #1118. nvx-cli is a library shell until the real binary moves; its nvx-testing development dependency is added in SL0.2d, so later source moves do not edit its manifest. The build output stays in nvx-rs/target, so CI, the scripts and the packages keep finding artifacts at their existing paths.

Notes.

PRs, in order. Each PR has one goal, leaves dev green, and names in its description each old test of its area as kept, rewritten or retired, with each change that check_test_changes.py reports. Its tests follow the repository's test layout: a module's unit tests, and the code that only they use, sit in its tests.rs or tests/ and move with it. The estimates count core lines (code, not comments, docs or tests) and counted files; each PR records its measured values. Each PR does what its Scope says and no more: a case, input or layout that its Scope doesn't name, and whatever "Not in this PR" lists, is out of scope. Address every review comment within the scope, and ask before acting on one that asks for more. A PR whose measured core lines pass the stop that its Estimate names (twice the estimate, at most 600) stops and asks before continuing.

  1. SL0.1: One Cargo workspace, with the build output where it was.

    • Objective: The repository becomes one Cargo workspace without moving the artifact paths used by CI, scripts and release packages. The excluded runtime adapter keeps its independent lockfile and target directory, while every build inventory starts following workspace-level inputs.
    • Contents: A root workspace whose member is nvx-rs. The test adapter stays outside it (the workspace's exclude lists it), with its own lockfile and, through its own .cargo/config.toml, its own target directory, until SL5.2 deletes it. [profile.guest], the lints and the lockfile move to the root. A root .cargo/config.toml keeps the build output in nvx-rs/target, so CI, the scripts and the packages keep finding artifacts at their existing paths; CI, the scripts and the Dockerfile run Cargo inside the repository, where that configuration applies. GuestRustBuildConstants' three input selectors (SOURCE_FILES, SOURCE_DIRECTORIES and SOURCE_PATTERN) and its SOURCE_PATHS, ReleaseBuildConstants.PROJECT_SOURCE_PATHS (scripts/nvx_tools/build_constants.py), and both of the Dockerfile's source-copy stages, take the root's manifest, lockfile and .cargo, and crates/, which crates/.gitkeep keeps in a clean checkout until SL0.2a adds its first crate.
    • Scope:
      • Add the root Cargo.toml workspace with nvx-rs as its member and tests/runtime-adapter in exclude; move [profile.guest], workspace lints and Cargo.lock to the root.
      • Add root .cargo/config.toml with target-dir = "nvx-rs/target", and give tests/runtime-adapter its own .cargo/config.toml for its existing target directory.
      • Update GuestRustBuildConstants' input selectors and source paths, plus ReleaseBuildConstants.PROJECT_SOURCE_PATHS, for the root manifest, lockfile, .cargo and crates/; SOURCE_PATTERN keeps excluding tests.rs and tests/ under both nvx-rs/src/ and crates/*/src/.
      • Update both Rust source-copy stages in docker/Dockerfile to copy the root workspace inputs and crates/ while retaining nvx-rs/.
      • Add crates/.gitkeep, so a clean checkout has the crates/ that the inventories and both Docker stages name before SL0.2a adds the first package.
    • Not in this PR:
      • Adding crates/* as workspace members or creating any new crate; SL0.2a through SL0.2d do that.
      • Moving Rust source modules, binaries or package manifests out of nvx-rs; later groups own those moves.
      • Moving build output to the root target/; existing consumers require nvx-rs/target.
      • Bringing tests/runtime-adapter into the workspace or sharing its lockfile and target directory; it remains independent until SL5.2.
      • Changing Cargo profiles, lint levels or build behavior beyond relocating their existing definitions.
      • Changing where CI, the scripts or the Dockerfile run Cargo; they already run inside the checkout, and SL0.2a adds the check action's --workspace flags.
    • Approach: Use Cargo's root workspace and one root configuration; do not add wrapper scripts or artifact-copy steps. Run Cargo with a working directory inside the checkout so nvx-rs/target remains effective. Update the existing fixed inventories and Docker copies directly, including crates/ before it contains members.
    • Done when:
      • Cargo commands from CI, scripts and both Docker build stages still place and find workspace artifacts under nvx-rs/target.
      • The runtime adapter builds and runs with its own lockfile and existing target directory outside the workspace.
      • Tests show all three guest input selectors, SOURCE_PATHS and PROJECT_SOURCE_PATHS include the root workspace inputs and crates/, while guest inputs exclude every crate's tests.rs and tests/; the layout check accepts the root workspace manifest as a crate.
      • A clean checkout contains tracked crates/.gitkeep, so both Docker source-copy stages can copy the root inputs, nvx-rs/ and crates/.
    • Needs: SL0.0a, in nvx-rs slimming 1.1.1: the public API is checked, and NVX's programs are hidden from it #1091; SL0.0b, in nvx-rs slimming 1.1.1: the public API is checked, and NVX's programs are hidden from it #1091.
    • Estimate: 80 core lines, 5 counted files. Past 160 core lines, stop and ask before continuing.
  2. SL0.2a: The OS crate exists, and CI checks every crate in crates/.

    • Objective: The workspace gains its first shared crate and CI begins checking the workspace rather than only nvx. nvx-sys starts as a dependency-ready shell, so the later OS-layer moves can land without another workspace or CI conversion.
    • Contents: The workspace takes crates/*, and crates/nvx-sys is an empty shell that declares the dependencies of its first moves and replaces crates/.gitkeep. The check action builds, lints and tests --workspace.
    • Scope:
      • Change the root workspace membership from only nvx-rs to nvx-rs plus crates/*.
      • Add crates/nvx-sys/Cargo.toml and its empty library shell, with the dependencies required by the first OS-layer moves.
      • Remove crates/.gitkeep, which crates/nvx-sys replaces; SL0.1's Docker stages already copy crates/.
      • Update .github/actions/check-nvx-rs/action.yml so formatting, builds, lints and tests cover --workspace on Linux and Windows.
    • Not in this PR:
    • Approach: Add the minimal manifest and library root that Cargo requires, using the workspace's version, edition and lints where applicable. Declare only dependencies already known to be needed by the first moves. Extend the existing check action with --workspace; do not add per-crate jobs or a crate generator.
    • Done when:
      • Cargo workspace metadata lists nvx-rs and the empty nvx-sys package, while excluding the runtime adapter.
      • The check action formats, builds, lints and tests the whole workspace on Linux and Windows.
      • The Docker Rust stages see the nvx-sys manifest through SL0.1's crates/ copy.
      • nvx-sys compiles as an empty library with the dependencies needed by its first moves.
    • Needs: SL0.1, above.
    • Estimate: 40 core lines, 4 counted files. Past 80 core lines, stop and ask before continuing.
  3. SL0.2b: The control and guest-tool crates exist.

    • Objective: The workspace gains stable destinations for the control protocol and guest binaries before their code moves. Their manifests establish publication and platform behavior now, avoiding manifest churn in the move PRs.
    • Contents: Empty shells: nvx-control, publish = false, with a host feature and a guest feature; nvx-guest-tools, empty on Windows, which nothing publishes until it has content (SL1.1a).
    • Scope:
      • Add the empty crates/nvx-control package with publish = false and separate host and guest features.
      • Add the empty crates/nvx-guest-tools package, configured to compile as an empty shell on Windows.
      • Keep nvx-guest-tools out of the publisher's active ordered list until SL1.1a gives it content.
      • Let the existing crates/* workspace membership and --workspace checks discover both packages.
    • Not in this PR:
      • Defining the control protocol or moving host and guest control code; later PRs populate nvx-control.
      • Moving guest binaries or their modules into nvx-guest-tools; SL1.1a and later move them.
      • Publishing nvx-control; it is repository-internal by design.
      • Publishing an empty nvx-guest-tools crate or adding it to nightly publication; SL1.1a does that after its first move.
      • Adding Windows guest-tool behavior; the package intentionally has no Windows implementation.
    • Approach: Create only the two manifests and minimal source roots. Express the two control features directly in its manifest and use ordinary conditional compilation for the guest-tool shell on Windows. Reuse workspace discovery and checks; do not add build scripts, feature abstractions or placeholder APIs.
    • Done when:
      • Workspace metadata lists nvx-control as unpublished with host and guest features.
      • Workspace metadata lists nvx-guest-tools, but the nightly publisher still lists only nvx.
      • Both empty shells pass the workspace checks, including an empty nvx-guest-tools build on Windows.
    • Needs: SL0.2a, above.
    • Estimate: 40 core lines, 4 counted files. Past 80 core lines, stop and ask before continuing.
  4. SL0.2c: The init and CLI crates exist.

    • Objective: The init and CLI packages exist with dependencies whose target crates are available. The CLI stays a library shell until its real binary moves, so exactly one package owns the executable and the later move need not edit the CLI manifest.
    • Contents: Empty shells, publish = false: nvx-init, empty on Windows, and nvx-cli, whose nvx dependency enables host and cli until SL3.1f. Declare final dependencies whose target crates exist, including nvx-control; add nvx-cli's development dependency on nvx-testing in SL0.2d. The CLI has no binary target or placeholder command yet. SL3.1d moves the real source to crates/nvx-cli/src/bin/nvx-rs.rs, where Cargo discovers it without changing the CLI manifest.
    • Scope:
      • Add the empty, unpublished crates/nvx-init package, configured to compile as an empty shell on Windows.
      • Add the empty, unpublished crates/nvx-cli library package without a [[bin]] declaration or a placeholder executable; retain Cargo's binary auto-discovery for the later source move.
      • Declare the final planned dependencies whose target crates exist, including nvx-control; defer the nvx-testing development dependency to SL0.2d.
      • For now, make nvx-cli's dependency on nvx enable the existing host and cli features, until SL3.1f removes that bridge.
      • Make only the three library lint/build/test commands with --no-default-features select -p nvx, not --workspace, so dependent packages cannot silently enable its features. Retain workspace-wide coverage elsewhere and extend the existing action test with a real Cargo feature-isolation regression.
      • Keep the workspace default-feature lint and test commands, and also add standalone clippy -p nvx --lib -- -D warnings and test -p nvx commands with the existing locked/toolchain arguments. This preserves the ordinary library configuration without cli, as well as coverage of every workspace package.
    • Not in this PR:
      • Moving PID 1, helper programs or guest space code into nvx-init; later PRs own those moves.
      • Moving the CLI implementation, store or command modules into nvx-cli; later PRs populate the shell.
      • Changing nvx's host or cli features; the shell consumes their current form until SL3.1f.
      • Publishing either crate; both remain repository-built packages.
      • Adding Windows behavior to nvx-init; its shell is intentionally empty there.
    • Approach: Add minimal library manifests and source roots using existing workspace dependencies and features. Do not declare a missing binary, disable binary auto-discovery, or add forwarding modules, placeholder commands or build scripts. Keep the original package as the sole owner of nvx-rs until SL3.1d moves the real source.
    • Done when:
      • Workspace metadata lists unpublished nvx-init and library-only nvx-cli packages with the planned dependencies whose target crates exist.
      • nvx-cli enables nvx's host and cli features, declares no binary yet, and exactly one package owns nvx-rs.
      • A real Cargo regression shows that the three isolated no-default-feature commands compile nvx without features despite the new dependent; the remaining checks still cover the workspace.
      • The additional isolated default-feature lint and test commands check nvx without dependency-enabled cli; the original workspace default-feature runs are retained. The regression verifies actual compiled feature sets for both configurations.
      • Both shells pass workspace checks, with nvx-init empty on Windows.
    • Needs: SL0.2b, above.
    • Estimate: 30 core lines, 4 counted files. Past 60 core lines, stop and ask before continuing.
  5. SL0.2d: The test crates exist.

    • Objective: The workspace gains dedicated packages for shared test support and public-API tests before those tests move. Establish the known test-support path dependencies without adding behavior; the API-test shell stays dependency-free until its tests arrive in SL5.1a.
    • Contents: Empty, unversioned shells, publish = false: nvx-testing depends on nvx with default-features = false and on nvx-control, without explicitly enabling features on either dependency. nvx-api-tests declares no dependencies until SL5.1a in nvx-rs slimming 4.1.1: public-API tests, and smoke tests on real VMs #1118. Once nvx-testing exists, add its planned development dependency to nvx-cli.
    • Scope:
      • Add the empty, unpublished crates/nvx-testing package with path dependencies on nvx (default-features = false) and nvx-control; neither dependency explicitly enables features. Registry dependencies move with the fake implementation in SL6.9, and the move that first needs a feature enables it.
      • Add the empty, unpublished crates/nvx-api-tests package with no dependencies. SL5.1a adds its nvx dependency and nvx-testing development dependency with the feature-set tests.
      • Add nvx-testing as the planned development dependency of nvx-cli, now that the target package exists; do not add placeholder test APIs.
      • Let the existing crates/* membership and --workspace checks discover and validate both packages.
    • Not in this PR:
      • Moving the fake OpenVMM or integration-test helpers into nvx-testing; later PRs populate it.
      • Adding public-API build matrices, examples, checklists or the test-case fate matrix; SL5.1a owns those tests.
      • Moving or rewriting runtime-adapter tests; the adapter remains outside the workspace.
      • Publishing either test crate; both are repository-only packages.
      • Adding placeholder test APIs merely to exercise dependencies; no caller needs them yet.
    • Approach: Create minimal library manifests and documented source roots, with no versions, edition 2024 and workspace lints. Declare only the two test-support path dependencies above and the CLI development dependency; leave the API-test shell dependency-free. Rely on workspace discovery and the existing workspace check action; do not add test harnesses, fixtures, generators or forwarding modules.
    • Done when:
      • Workspace metadata lists unpublished nvx-testing and nvx-api-tests packages.
      • Metadata shows nvx-testing's two path dependencies, no explicitly enabled dependency features and disabled default features for its nvx dependency; nvx-api-tests declares no dependencies.
      • Workspace metadata resolves nvx-cli's development dependency to the new nvx-testing package.
      • Both empty packages pass the workspace formatting, lint, build and test commands.
    • Needs: SL0.2b and SL0.2c, above; the latter supplies nvx-cli for its development dependency.
    • Estimate: 20 core lines, 2 counted files. Past 40 core lines, stop and ask before continuing.

Tests. CI builds, lints and tests --workspace, except the three library commands that check nvx without default features: those use -p nvx to prevent dependency feature unification from invalidating the check. Two additional -p nvx commands preserve its default-feature lint and test coverage without replacing the workspace runs. Checks show that CI, the scripts and the Dockerfile's build stages run Cargo inside the repository, and still find the workspace's artifacts in nvx-rs/target. The test adapter, with its own lockfile and .cargo/config.toml, builds in its existing target directory and still runs. The guest build's input selectors, SOURCE_PATHS, PROJECT_SOURCE_PATHS and both of the Dockerfile's source-copy stages take the root's manifest, lockfile and .cargo, then crates/.

Done when: every PR above has merged, with dev green.

Activity

  1. esaurez commented on Nov 3, 2026

    @esaurez
    ContributorAuthor

    Closing as not planned: the plan in #1076 changed. nvx stays the only crate, with no Cargo workspace and no new crates. NVX's own programs, its control protocol and the OS layers stay in nvx, private to it, and CI checks the public API against committed snapshots (#1091). Its root workspace and the new crates' empty shells have no use.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions