Skip to content

Releases: devlooped/ndnx

v0.6.0

Choose a tag to compare

@devlooped-bot devlooped-bot released this 15 Aug 20:49

Keep floating versions evergreen with a graceful child restart.

Evergreen

A floating version — unspecified, @*, @*-*, or a NuGet range — stays current. ndnx starts the latest match, watches the feed, downloads a newer matching version before stopping the child, then sends SIGINT / Ctrl+C (and WM_CLOSE if the tool is a GUI) and restarts.

ndnx stop                 # latest stable, restart when a newer one lands
ndnx stop@*               # same
ndnx stop@*-*             # include prerelease
ndnx stop@[2.0,3.0)       # stay on the newest 2.x
ndnx stop@2.1.0           # exact pin: one-shot, no loop

Short tools still exit as soon as the child exits. Only a long-running child is watched and restarted.

The new package is staged in the global packages folder first, so the old process keeps running until the update is on disk. If the child exits on its own during that window, ndnx returns that exit code and does not restart.

The poll interval defaults to 5 seconds and can be set in .netconfig:

[ndnx]
    interval = 5

ndnx walks from the working directory up, then ~/.netconfig. --verbosity quiet hides the Updating … line.

Sponsors

The following sponsors made this release possible: @clarius, @MFB-Technologies-Inc, @sandrock, @drivenet, @Keflon, @tbolon, @kfrancis, @rbnswartz, @jfoshee, @Mrxx99, @eajhnsn1, @Jonathan-Hickey, @KenBonny, @SimonCropp, @agileworks-eu, @arsdragonfly, @vezel-dev, @ChilliCream, @4OTC, @DominicSchell, @adalon, @torutek, @mccaffers, @SeikaLogiciel, @wizardness, @eska-gmbh, @geodata-no.

Thanks 💜

v0.5.2

Choose a tag to compare

@devlooped-bot devlooped-bot released this 15 Aug 15:45

Hash the root .nuspec like dnx instead of SHA512 of the whole nupkg.

Package hash

.nupkg.sha512 (and .nupkg.metadata contentHash) is now Base64(SHA512(root nuspec)) — the same shortcut dnx writes via CryptoHashProvider("SHA512").CalculateHash(reader.GetNuspec()).

Restore hashes the entire nupkg. Tool packages are never part of a plain dotnet restore, can be large (Native AOT RID payloads), and only the manifest is needed to recognize an install. Packages already extracted by dnx stay cache hits.

Sponsors

The following sponsors made this release possible: @clarius, @MFB-Technologies-Inc, @sandrock, @drivenet, @Keflon, @tbolon, @kfrancis, @rbnswartz, @jfoshee, @Mrxx99, @eajhnsn1, @Jonathan-Hickey, @KenBonny, @SimonCropp, @agileworks-eu, @arsdragonfly, @vezel-dev, @ChilliCream, @4OTC, @DominicSchell, @adalon, @torutek, @mccaffers, @SeikaLogiciel, @wizardness, @eska-gmbh, @geodata-no.

Thanks 💜

v0.5.1

Choose a tag to compare

@devlooped-bot devlooped-bot released this 15 Aug 06:53

v0.5.0

Choose a tag to compare

@devlooped-bot devlooped-bot released this 15 Aug 06:42

Download tool@version from the constructed nupkg URL — no version-index round-trip unless that GET is 404.

Exact-version download

A first ndnx stop@2.1.0 now:

  1. Resolves PackageBaseAddress from the v3 service index (kept in memory for the process)
  2. GETs {base}{id}/{version}/{id}.{version}.nupkg
  3. Lists versions only if that GET returns 404

A RID hop (stopstop.win-x64) reuses the cached service index and the same constructed URL, so index.json is not fetched again.

Unspecified version or @* still lists the feed for latest, same as dnx. An exact version already in the global packages folder is still a cache hit with no network.

Startup time

Cold is empty-cache download → start; cached is start only (tool@version). linux-x64 (WSL2) is SDK 10.0.110; win-x64 is SDK 10.0.303.

Tool Runner Cold linux-x64 Cold win-x64 Cached linux-x64 Cached win-x64
stop@2.1.0 (native AOT) dnx 2.2 s 2.1 s 580 ms 520 ms
ndnx 1.2 s 1.5 s 10 ms 34 ms
dotnetsay@1.0.0 (framework-dependent) dnx 1.6 s 1.8 s 570 ms 545 ms
ndnx 849 ms 1.1 s 12 ms 50 ms

Isolated NUGET_PACKAGES, source https://kzu.blob.core.windows.net/nuget/index.json. Cold is the median of 3 empty-cache runs. Cached is the median of 10 runs after one seed.

Sponsors

The following sponsors made this release possible: @clarius, @MFB-Technologies-Inc, @sandrock, @drivenet, @Keflon, @tbolon, @kfrancis, @rbnswartz, @jfoshee, @Mrxx99, @eajhnsn1, @Jonathan-Hickey, @KenBonny, @SimonCropp, @agileworks-eu, @arsdragonfly, @vezel-dev, @ChilliCream, @4OTC, @DominicSchell, @adalon, @torutek, @mccaffers, @SeikaLogiciel, @wizardness, @eska-gmbh, @geodata-no.

Thanks 💜

v0.4.0

Choose a tag to compare

@devlooped-bot devlooped-bot released this 15 Aug 05:49

Skip the NuGet feed when tool@version is already cached, so a warm native tool starts in tens of milliseconds.

Cached exact versions

Like dnx's GetBestPackageVersionAsync, an exact version is the answer:

ndnx stop@2.1.0 -- --help
ndnx stop --version 2.1.0 -- --help

If that package is already in the global packages folder, ndnx does not query the feed. RID-specific hops (stopstop.win-x64) use the same installed check.

Unspecified version or @* still resolve latest from the feed, same as dnx.

Startup time

Cold start is download + launch. Cached start is launch only, with an exact version so neither runner has to resolve latest.

Tool Runner Cold (download → start) Cached (start)
stop@2.1.0 (native AOT) dnx 5.6 s 563 ms
ndnx 5.6 s 33 ms
dotnetsay@1.0.0 (framework-dependent) dnx 4.6 s 585 ms
ndnx 4.8 s 51 ms

win-x64, .NET SDK 11.0.100-preview.6, isolated NUGET_PACKAGES, source https://pkg.kzu.app/index.json. Cold is the median of 3 empty-cache runs. Cached is the median of 10 runs after one seed.

Gzip v3 feeds

HttpClient now enables automatic decompression, so gzip-compressed NuGet v3 indexes (including static Sleet feeds such as https://pkg.kzu.app/index.json) parse instead of failing with 0x1F is an invalid start of a value.

Docs

The readme now shows side-by-side dnx / ndnx / dotnet dnx examples, shared cache and flags, and the timings above.

Sponsors

The following sponsors made this release possible: @clarius, @MFB-Technologies-Inc, @sandrock, @drivenet, @Keflon, @tbolon, @kfrancis, @rbnswartz, @jfoshee, @Mrxx99, @eajhnsn1, @Jonathan-Hickey, @KenBonny, @SimonCropp, @agileworks-eu, @arsdragonfly, @vezel-dev, @ChilliCream, @4OTC, @DominicSchell, @adalon, @torutek, @mccaffers, @SeikaLogiciel, @wizardness, @eska-gmbh, @geodata-no.

Thanks 💜

v0.3.0

Choose a tag to compare

@kzu kzu released this 15 Aug 02:33

Share the NuGet global packages cache with dnx and restore, and fail clearly when a framework-dependent tool needs a newer runtime than the host dotnet.

NuGet v3 cache

ndnx now installs one-shot tools into the same folder restore uses (NUGET_PACKAGES, nuget.config's globalPackagesFolder, or ~/.nuget/packages). NDNX_STORE still overrides that for isolated runs.

The on-disk layout matches NuGet, not a private .ndnx-ok dump:

  • {id}/{version}/{id}.{version}.nupkg
  • {id}.{version}.nupkg.sha512 is Base64(SHA512(nupkg bytes)) — the restore algorithm, not dnx's nuspec-hash shortcut
  • .nupkg.metadata is written last, which is how NuGet decides the install finished

A package already extracted by dnx or dotnet restore is reused. Packages ndnx writes are visible to dnx and restore.

Framework-dependent tools

Runner=executable (native / AOT tools) is unchanged.

Runner=dotnet is checked against the muxer (DOTNET_ROOT, then PATH), not ndnx's own compile-time TFM. If the tool needs .NET 10 and that dotnet only has 8.0.19, ndnx exits before launch:

This tool requires .NET 10.0. The 'dotnet.exe' at 'C:\Program Files\dotnet\dotnet.exe' has Microsoft.NETCore.App 8.0.19.

Packages with several tools/{tfm}/ groups pick the newest TFM that muxer can load.

Other

ndnx --version

prints the ndnx version and exits.

v0.2.0

Choose a tag to compare

@kzu kzu released this 14 Aug 18:00

Self-update the installed ndnx binary from GitHub Releases.

Self-update

ndnx --update (with no package identity) checks GitHub Releases, prints the version being installed, replaces the running binary, and exits.

ndnx --update          # latest stable release
ndnx --update 0.1.1    # exact version, including downgrades

A leading v is accepted (--update v0.1.1). --update=0.1.1 and --update --version 0.1.1 work too.

If you are already on that version, ndnx says so and does nothing. Otherwise it downloads the RID archive (win-x64, linux-arm64, …) and its .sha256, verifies the hash, and swaps the executable. On Windows the running file is renamed first so the replace can succeed.

NDNX_REPO still overrides which GitHub repository is used (same as the install scripts).

--update cannot be combined with a package name or extra tool arguments.

Sponsors

The following sponsors made this release possible: @clarius, @MFB-Technologies-Inc, @sandrock, @drivenet, @Keflon, @tbolon, @kfrancis, @rbnswartz, @jfoshee, @Mrxx99, @eajhnsn1, @Jonathan-Hickey, @KenBonny, @SimonCropp, @agileworks-eu, @arsdragonfly, @vezel-dev, @ChilliCream, @4OTC, @DominicSchell, @adalon, @torutek, @mccaffers, @SeikaLogiciel, @wizardness, @eska-gmbh, @geodata-no.

Thanks 💜

v0.1.1

Choose a tag to compare

@kzu kzu released this 14 Aug 16:53

Multi-RID (RID-specific) .NET tools now run instead of failing on the wrapper package.

Multi-RID tool packages

.NET 10 can pack a tool as a thin wrapper plus per-RID nupkgs (RuntimeIdentifierPackages in DotnetToolSettings.xml). v0.1.0 stopped on those wrappers with declares RID-specific packages, which are not resolved by this runner.

ndnx now hops the same way the SDK does:

  • Pick the best declared RID for this machine (exact host RID, then the portable RID graph — e.g. ubuntu.24.04-x64linux-x64 — then any)
  • Download that mapped package at the same version
  • Run the RID package’s EntryPoint + Runner

That unblocks Native AOT tools such as stop and winget, and the same layout used by go, runfile, and gist. Classic tools/{tfm}/{rid} packages are unchanged.

Executable payloads extracted from nupkgs also get Unix execute bits, so RID binaries actually run after extract on macOS and Linux.

Packaging

Windows release zips are submitted to WinGet (Devlooped.ndnx) after a published GitHub release.

Sponsors

The following sponsors made this release possible: @clarius, @MFB-Technologies-Inc, @sandrock, @drivenet, @Keflon, @tbolon, @kfrancis, @rbnswartz, @jfoshee, @Mrxx99, @eajhnsn1, @Jonathan-Hickey, @KenBonny, @SimonCropp, @agileworks-eu, @arsdragonfly, @vezel-dev, @ChilliCream, @4OTC, @DominicSchell, @adalon, @torutek, @mccaffers, @SeikaLogiciel, @wizardness, @eska-gmbh, @geodata-no.

Thanks 💜

v0.1.0

Choose a tag to compare

@kzu kzu released this 13 Aug 23:19

Initial public release of ndnx.

Native AOT binaries for Windows, macOS, and Linux (x64 and arm64), plus install scripts.

Sponsors

The following sponsors made this release possible: @clarius, @MFB-Technologies-Inc, @sandrock, @drivenet, @Keflon, @tbolon, @kfrancis, @rbnswartz, @jfoshee, @Mrxx99, @eajhnsn1, @Jonathan-Hickey, @KenBonny, @SimonCropp, @agileworks-eu, @arsdragonfly, @vezel-dev, @ChilliCream, @4OTC, @DominicSchell, @adalon, @torutek, @mccaffers, @SeikaLogiciel, @wizardness, @eska-gmbh, @geodata-no.

Thanks 💜