refactor(runtimes): split provider files to slim shim binary#266
Merged
Conversation
Move heavy install/list/migrate methods (Install, Uninstall, ListInstalled, ListAvailable, DetectInstalled, GlobalPackages, InstallGlobalPackages, ManualPackageInstallCommand, plus install helpers) and the version getters/setters into provider_full.go files tagged //go:build !shim. Provider remains an alias for ShimProvider in shim builds via the new provider_shim.go, so the registry and its callers don't change. The Node.js lifecycle helper and runtime test harness are also tagged !shim. Build the shim with -tags shim (rnr.yaml + both CI workflows) so the linker drops net/http, klauspost/compress, sevenzip, brotli, lz4, xz, bzip2, archive/zip, crypto/tls, afero, hashicorp/golang-lru, progressbar, the embedded manifest JSON, and the Node release schedule. Shim drops from 5.70 MB to 2.68 MB (-53%); main CLI is unchanged.
Contributor
Author
|
/release-note Shim binary is now 67% smaller (8.2 MB → 2.7 MB), reducing disk footprint and cold-start cost for every shimmed command! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Splits each runtime provider (node, python, ruby) into a "shim half" (lite methods only) and a "full half" tagged
//go:build !shim. Build the shim with-tags shimand the linker drops every heavy transitive dependency the shim never actually used.Measured impact
dtvem-shim.exedtvem.exeCombined with the
-trimpathwork in #264, the shim is now 2.68 MB versus 8.20 MB onf1dfab5(pre‑#264) — a −67% total reduction since this slimming effort started.Symbol audit — what's gone
go tool nmon the new shim no longer contains any of:github.com/bodgit/sevenzip(was 173 symbols)github.com/klauspost/compress(was 235)net/http(was 114)github.com/ulikunitz/xz(was 102)github.com/pierrec/lz4(was 93)github.com/andybalholm/brotli(was 74)compress/bzip(was 50)archive/zip/archive/tar/compress/gzip(was 34 combined)crypto/tls(was 22)github.com/spf13/afero(was 10)github.com/hashicorp/golang-lru(was 10)github.com/schollz/progressbar(was 3)github.com/bodgit/plumbing(was 3)internal/manifest/data/*.json)runtimes/node/data/schedule.json)testingpackage (transitively viaprovider_test_harness.go)What remains is
encoding/json(for the shim‑map and runtimes.json),fatih/color+mattn/go-isatty+mattn/go-colorable(the user‑facing error output), and dtvem's own code.Approach
One change to interface shape, the rest is a mechanical file split.
internal/runtime/provider.go— keepsShimProvider.internal/runtime/provider_full.go(//go:build !shim) — defines the fullProviderinterface with all heavy methods.internal/runtime/provider_shim.go(//go:build shim) —type Provider = ShimProvider(alias).Because
Provideralways exists as a public type, the registry and its callers (includinginternal/shim/manager.goand everycmd/*.gofile) need no changes. In default builds Provider is the full interface; in shim builds it collapses to ShimProvider and the heavy method calls on concrete types are gone — soklauspost/compress, sevenzip, et al. are no longer reachable.Per‑runtime split (
src/runtimes/{node,python,ruby}/):provider.go(untagged) —Name,DisplayName,Shims,ExecutablePath,IsInstalled,InstallPath,ShouldReshimAfter,GetEnvironment,init(). Imports stay minimal:fmt,os,filepath,runtime,internal/config,internal/constants,internal/runtime.provider_full.go(//go:build !shim) —Install,Uninstall,ListInstalled,ListAvailable,DetectInstalled,GlobalPackages,InstallGlobalPackages,ManualPackageInstallCommand, all version setters/getters, all install helpers. Heavy imports (internal/download,internal/manifest,internal/shim,internal/ui,encoding/json,os/exec, etc.) live only here.Extras tagged
!shim:internal/runtime/provider_test_harness.go— uses fullProvidermethods on a concrete value; only consumed by tests (default build).runtimes/node/lifecycle.go— embedsdata/schedule.jsonand is only used bylist-all.Build config:
-tags shimadded to thebuild-shimstep inrnr.yaml,.github/workflows/build.yml, and.github/workflows/release.yml. Main CLI build is untagged.Test plan
./rnr.cmd checkpasses (format, lint, full test suite — every package green)go build ./...succeeds under the default buildgo build -tags shim ./src/cmd/shimsucceedsgo tool nm) confirms the heavy packages are no longer presentpython --version/node --version/ruby --versionthrough the shimmed executables, verify "no version configured" fallback still worksRisk
Mechanical refactor. Watch points:
cmd/shimthat calls full‑Providermethods needs to be in!shimfiles so the shim build compiles. Validated by build success on both tag configurations; the only file that needed tagging wasprovider_test_harness.go(andnode/lifecycle.go, which is already tagged for the secondary win of dropping the embedded schedule).ShimProvider(==Providerin that build). In default builds they satisfy the fullProvider. Verified bygo vet+go test.Resolves #265