From 6fad21b3496a1b5afe238e4df75f56d360e03a2f Mon Sep 17 00:00:00 2001 From: Payton McIntosh Date: Tue, 28 Jul 2026 10:01:42 +0100 Subject: [PATCH 1/3] Document v0.1.0 installation packages Describe the crates.io release and the Linux, macOS, and Windows installer matrix as published user-facing options. Include platform installation commands, payload details, prerequisites, and checksum guidance. Keep the README and user's guide aligned through the executable documentation contract. --- README.md | 22 ++++++++++++++--- docs/users-guide.md | 35 ++++++++++++++++++++++++--- tests/documentation_examples_tests.rs | 18 ++++++++++++++ 3 files changed, 67 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 9500e8ae..5ee70ace 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ Netsuke currently requires: ### Installation -To install from crates.io: +Netsuke v0.1.0 is available from crates.io: @@ -45,6 +45,21 @@ To install from crates.io: cargo install netsuke ``` +Pre-built installers are available from the +[v0.1.0 GitHub release](https://github.com/leynos/netsuke/releases/tag/v0.1.0): + +| Platform | Architectures | Packages | +| -------- | ------------------------------------ | -------------------------------- | +| Linux | x86-64 (`amd64`) and Arm64 (`arm64`) | Debian (`.deb`) and RPM (`.rpm`) | +| macOS | Intel x86-64 and Apple silicon Arm64 | Installer package (`.pkg`) | +| Windows | x64 and Arm64 | Windows Installer (`.msi`) | + +The Linux packages install the `netsuke` manual page and declare `ninja-build` +as a dependency. Ninja must be installed separately when using the macOS or +Windows installer. SHA-256 checksum files accompany the downloadable release +files. See the [user's guide](docs/users-guide.md#install-netsuke) for +platform-specific commands. + To install the current source checkout with Cargo: @@ -110,9 +125,8 @@ The core build-system compiler is implemented: - unit, behavioural, integration, property, snapshot, and initial Kani verification coverage. -Release automation is configured to build packages for Linux, macOS, and -Windows, including platform help artefacts. v0.1.0 will be the first public -release of this work. +The v0.1.0 release provides packages for Linux, macOS, and Windows, including +platform help artefacts. It is the first public release of this work. ______________________________________________________________________ diff --git a/docs/users-guide.md b/docs/users-guide.md index cd142a9f..1b2e4a63 100644 --- a/docs/users-guide.md +++ b/docs/users-guide.md @@ -13,7 +13,7 @@ change before 1.0. Pin the Netsuke version in automated workflows. Netsuke requires [Ninja](https://ninja-build.org/) on `PATH`. A source build also requires Rust 1.89 or later. -To install a published release from crates.io: +Netsuke v0.1.0 is available from crates.io: @@ -21,6 +21,34 @@ To install a published release from crates.io: cargo install netsuke ``` +Pre-built installers are available from the +[v0.1.0 GitHub release](https://github.com/leynos/netsuke/releases/tag/v0.1.0): + +| Platform | Architectures | Packages | +| -------- | ------------------------------------ | -------------------------------- | +| Linux | x86-64 (`amd64`) and Arm64 (`arm64`) | Debian (`.deb`) and RPM (`.rpm`) | +| macOS | Intel x86-64 and Apple silicon Arm64 | Installer package (`.pkg`) | +| Windows | x64 and Arm64 | Windows Installer (`.msi`) | + +Download the package for the host architecture, then install it with the +platform tool. Replace `PACKAGE` with the downloaded filename: + +- Debian or Ubuntu: `sudo apt install ./PACKAGE.deb` +- Fedora, Rocky Linux, or another RPM-based distribution: + `sudo dnf install ./PACKAGE.rpm` +- macOS: `sudo installer -pkg ./PACKAGE.pkg -target /` +- Windows: `msiexec.exe /i PACKAGE.msi` + +The Linux packages install the binary under `/usr/bin`, add the `netsuke.1` +manual page and declare `ninja-build` as a dependency. The macOS packages +install the binary under `/usr/local/bin`, along with the manual page and +licence. Ninja must be installed separately when using the macOS or Windows +installer. + +SHA-256 checksum files accompany the downloadable release files. Windows +PowerShell help files are published beside each MSI as sidecar artefacts rather +than embedded in the installer. + To install the current source checkout with Cargo: @@ -31,9 +59,8 @@ cd netsuke cargo install --path . ``` -Release archives contain platform-specific packages and help artefacts. Unix -archives include a `netsuke.1` manual page. Windows archives include PowerShell -external help: +After installing the Windows PowerShell help sidecars, inspect the external +help with: diff --git a/tests/documentation_examples_tests.rs b/tests/documentation_examples_tests.rs index 4f6d65a3..187188c6 100644 --- a/tests/documentation_examples_tests.rs +++ b/tests/documentation_examples_tests.rs @@ -162,6 +162,24 @@ fn installation_examples_match_source_and_release_contracts() -> Result<()> { "user's guide crates.io install drifted" ); + let expected_release_details = [ + "https://github.com/leynos/netsuke/releases/tag/v0.1.0", + "Debian (`.deb`) and RPM (`.rpm`)", + "Installer package (`.pkg`)", + "Windows Installer (`.msi`)", + "x86-64 (`amd64`) and Arm64 (`arm64`)", + "SHA-256 checksum files", + ]; + for path in ["README.md", "docs/users-guide.md"] { + let document = test_fs::read_to_string(path).with_context(|| format!("read {path}"))?; + for expected in expected_release_details { + ensure!( + document.contains(expected), + "{path} should document v0.1.0 release detail: {expected}" + ); + } + } + let readme = documented_example("readme-source-install")?; let guide = documented_example("guide-source-install")?; let expected = concat!( From a0ed1b9b442e142ba35a12bbb8d22513f1b72ede Mon Sep 17 00:00:00 2001 From: Payton McIntosh Date: Tue, 28 Jul 2026 15:02:53 +0100 Subject: [PATCH 2/3] Complete Windows installer guidance Document the MSI installation directory and persistent PATH setup so the installed command resolves in new and current PowerShell sessions. Add an architecture-aware download and module-install flow for the staged PowerShell help files. Narrow the checksum claim to the staged files that actually receive sidecars and state that v0.1.0 installers are not covered. --- README.md | 8 ++- docs/users-guide.md | 86 +++++++++++++++++++++++++-- tests/documentation_examples_tests.rs | 15 ++++- 3 files changed, 99 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 5ee70ace..b695c067 100644 --- a/README.md +++ b/README.md @@ -56,9 +56,11 @@ Pre-built installers are available from the The Linux packages install the `netsuke` manual page and declare `ninja-build` as a dependency. Ninja must be installed separately when using the macOS or -Windows installer. SHA-256 checksum files accompany the downloadable release -files. See the [user's guide](docs/users-guide.md#install-netsuke) for -platform-specific commands. +Windows installer. The Windows MSI installs to `C:\Program Files\netsuke` and +does not update `PATH`. SHA-256 checksum files accompany standalone binaries +and staged help and licence files. Installer packages do not have checksum +sidecars in v0.1.0. See the [user's guide](docs/users-guide.md#install-netsuke) +for platform-specific commands and Windows setup. To install the current source checkout with Cargo: diff --git a/docs/users-guide.md b/docs/users-guide.md index 1b2e4a63..fa188a4b 100644 --- a/docs/users-guide.md +++ b/docs/users-guide.md @@ -43,11 +43,13 @@ The Linux packages install the binary under `/usr/bin`, add the `netsuke.1` manual page and declare `ninja-build` as a dependency. The macOS packages install the binary under `/usr/local/bin`, along with the manual page and licence. Ninja must be installed separately when using the macOS or Windows -installer. +installer. The Windows MSI installs to `C:\Program Files\netsuke` and does not +update `PATH`. -SHA-256 checksum files accompany the downloadable release files. Windows -PowerShell help files are published beside each MSI as sidecar artefacts rather -than embedded in the installer. +SHA-256 checksum files accompany standalone binaries and staged help and +licence files. Installer packages do not have checksum sidecars in v0.1.0. +Windows PowerShell help files are published beside each MSI as sidecar +artefacts rather than embedded in the installer. To install the current source checkout with Cargo: @@ -59,8 +61,80 @@ cd netsuke cargo install --path . ``` -After installing the Windows PowerShell help sidecars, inspect the external -help with: +### Complete Windows setup + +The MSI does not add its installation directory to `PATH`. Add it to the +current user's persistent `PATH`, update the current PowerShell session, then +verify that the command resolves: + + + +```powershell +$netsukeDirectory = Join-Path $env:ProgramFiles 'netsuke' +$userPath = [Environment]::GetEnvironmentVariable('Path', 'User') +$userEntries = @($userPath -split ';' | Where-Object { $_ }) +if ($userEntries -notcontains $netsukeDirectory) { + $newUserPath = (($userEntries + $netsukeDirectory) -join ';') + [Environment]::SetEnvironmentVariable('Path', $newUserPath, 'User') +} +if (($env:Path -split ';') -notcontains $netsukeDirectory) { + $env:Path = "$env:Path;$netsukeDirectory" +} +netsuke --version +``` + +The release publishes PowerShell help separately for each Windows architecture. +The following script downloads the matching module script, manifest, Microsoft +Assistance Markup Language (MAML) help, and about-help file. It then restores +the versioned module layout under the current user's standard PowerShell module +directory and imports the module. Set `$architecture` to match the downloaded +MSI: + + + +```powershell +$architecture = 'amd64' # Use 'arm64' for the Arm64 MSI. +$releaseUri = 'https://api.github.com/repos/leynos/netsuke/releases/tags/v0.1.0' +$release = Invoke-RestMethod -Uri $releaseUri + +$documents = [Environment]::GetFolderPath('MyDocuments') +$editionDirectory = if ($PSVersionTable.PSEdition -eq 'Desktop') { + 'WindowsPowerShell' +} else { + 'PowerShell' +} +$moduleRoot = Join-Path $documents "$editionDirectory\Modules" +$moduleDirectory = Join-Path $moduleRoot 'Netsuke\0.1.0' +$helpDirectory = Join-Path $moduleDirectory 'en-US' +New-Item -ItemType Directory -Path $helpDirectory -Force | Out-Null + +$patterns = @{ + 'Netsuke.psm1' = '*Netsuke.psm1' + 'Netsuke.psd1' = '*Netsuke.psd1' + 'Netsuke-help.xml' = '*en-US-Netsuke-help.xml' + 'about_Netsuke.help.txt' = '*en-US-about_Netsuke.help.txt' +} +$localizedFiles = @('Netsuke-help.xml', 'about_Netsuke.help.txt') +foreach ($fileName in $patterns.Keys) { + $pattern = "*windows-$architecture*$($patterns[$fileName])" + $asset = $release.assets | Where-Object { $_.name -like $pattern } | Select-Object -First 1 + if ($null -eq $asset) { + throw "Release asset not found: $pattern" + } + $destinationDirectory = if ($localizedFiles -contains $fileName) { + $helpDirectory + } else { + $moduleDirectory + } + $destination = Join-Path $destinationDirectory $fileName + Invoke-WebRequest -Uri $asset.browser_download_url -OutFile $destination -UseBasicParsing +} + +Import-Module (Join-Path $moduleDirectory 'Netsuke.psd1') -Force +``` + +The versioned directory is discoverable in later PowerShell sessions. After the +import, inspect the external help with: diff --git a/tests/documentation_examples_tests.rs b/tests/documentation_examples_tests.rs index 187188c6..d7986572 100644 --- a/tests/documentation_examples_tests.rs +++ b/tests/documentation_examples_tests.rs @@ -34,6 +34,8 @@ const EXPECTED_EXAMPLE_IDS: &[&str] = &[ "guide-source-install", "guide-utility-commands", "guide-windows-help", + "guide-windows-help-install", + "guide-windows-path", "readme-crates-io-install", "readme-first-build-commands", "readme-first-build-manifest", @@ -168,7 +170,8 @@ fn installation_examples_match_source_and_release_contracts() -> Result<()> { "Installer package (`.pkg`)", "Windows Installer (`.msi`)", "x86-64 (`amd64`) and Arm64 (`arm64`)", - "SHA-256 checksum files", + "Installer packages do not have checksum", + "The Windows MSI installs to `C:\\Program Files\\netsuke`", ]; for path in ["README.md", "docs/users-guide.md"] { let document = test_fs::read_to_string(path).with_context(|| format!("read {path}"))?; @@ -198,6 +201,16 @@ fn installation_examples_match_source_and_release_contracts() -> Result<()> { windows.body == "Get-Help Netsuke -Full\n", "PowerShell help command drifted" ); + let windows_path = documented_example("guide-windows-path")?; + ensure!( + windows_path.body.contains("SetEnvironmentVariable"), + "Windows PATH setup should persist the MSI installation directory" + ); + let windows_help_install = documented_example("guide-windows-help-install")?; + ensure!( + windows_help_install.body.contains("Import-Module"), + "Windows help setup should import the downloaded sidecars" + ); let staging = test_fs::read_to_string(".github/release-staging.toml") .context("read release staging configuration")?; ensure!( From 20820651f4503544ea8b79b5c3d8336f05148c44 Mon Sep 17 00:00:00 2001 From: Payton McIntosh Date: Tue, 28 Jul 2026 18:47:43 +0100 Subject: [PATCH 3/3] Strengthen Windows documentation contracts Assert the user-scoped `Path` update, MSI directory variable, versioned PowerShell module import, and architecture-aware release asset selection. Keep the documentation test within the repository's file-size limit. --- tests/documentation_examples_tests.rs | 42 +++++++++++++-------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/tests/documentation_examples_tests.rs b/tests/documentation_examples_tests.rs index d7986572..b6618336 100644 --- a/tests/documentation_examples_tests.rs +++ b/tests/documentation_examples_tests.rs @@ -155,15 +155,8 @@ fn installation_examples_match_source_and_release_contracts() -> Result<()> { let readme_release = documented_example("readme-crates-io-install")?; let guide_release = documented_example("guide-crates-io-install")?; let expected_release = "cargo install netsuke\n"; - ensure!( - readme_release.body == expected_release, - "README crates.io install drifted" - ); - ensure!( - guide_release.body == expected_release, - "user's guide crates.io install drifted" - ); - + ensure!(readme_release.body == expected_release, "README drifted"); + ensure!(guide_release.body == expected_release, "user guide drifted"); let expected_release_details = [ "https://github.com/leynos/netsuke/releases/tag/v0.1.0", "Debian (`.deb`) and RPM (`.rpm`)", @@ -182,7 +175,6 @@ fn installation_examples_match_source_and_release_contracts() -> Result<()> { ); } } - let readme = documented_example("readme-source-install")?; let guide = documented_example("guide-source-install")?; let expected = concat!( @@ -191,24 +183,32 @@ fn installation_examples_match_source_and_release_contracts() -> Result<()> { "cargo install --path .\n" ); ensure!(readme.body == expected, "README source install drifted"); - ensure!( - guide.body == expected, - "user's guide source install drifted" - ); - + ensure!(guide.body == expected, "user guide source install drifted"); let windows = documented_example("guide-windows-help")?; - ensure!( - windows.body == "Get-Help Netsuke -Full\n", - "PowerShell help command drifted" - ); + ensure!(windows.body == "Get-Help Netsuke -Full\n", "help drifted"); let windows_path = documented_example("guide-windows-path")?; + let windows_path_fragments = [ + "SetEnvironmentVariable", + "$netsukeDirectory", + "SetEnvironmentVariable('Path', $newUserPath, 'User')", + ]; ensure!( - windows_path.body.contains("SetEnvironmentVariable"), + windows_path_fragments + .into_iter() + .all(|fragment| windows_path.body.contains(fragment)), "Windows PATH setup should persist the MSI installation directory" ); let windows_help_install = documented_example("guide-windows-help-install")?; + let windows_help_fragments = [ + "Import-Module", + "$moduleDirectory = Join-Path $moduleRoot 'Netsuke\\0.1.0'", + "Import-Module (Join-Path $moduleDirectory 'Netsuke.psd1')", + "*windows-$architecture*", + ]; ensure!( - windows_help_install.body.contains("Import-Module"), + windows_help_fragments + .into_iter() + .all(|fragment| windows_help_install.body.contains(fragment)), "Windows help setup should import the downloaded sidecars" ); let staging = test_fs::read_to_string(".github/release-staging.toml")