feat: convert the git tool to a typescript installer - #7436
Conversation
Replaces the last v1 shell tool with a `GitInstallService` and a `GitPrepareService`. The prepare step adds the `git-core` ppa keyring and source list, the install step runs apt through `AptService` and verifies the installed version is at least 2.33.0, and uninstall removes the package again via a new `AptService.remove`. git still requires root, which is enforced by a `needsRoot` flag on the install service: the cli now reports `NotRoot` with a clear message instead of failing somewhere inside apt. Co-Authored-By: Claude Opus 5 <michael.kriese+claude-code@mend.io>
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (5)
Included review availability: Your plan provides up to 10 included reviews per hour; 7 remain after this review. 📝 WalkthroughWalkthroughThe CLI now checks root requirements during installation and uninstallation, and checks whether a tool supports uninstallation. Git preparation and installation use registered CLI services. Git version parsing accepts vendor-suffixed output, and the former Git installation shell script was removed. ChangesGit CLI installation and root checks
Priority: ⬇️ Low Estimated code review effort: 3 (Moderate) | ~25 minutes Change: Feature Merge Risk: ⚪ Minimal · up to Git installation and preparation use the registered CLI services, and no merge-blocking risk remains. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Comment |
`etc/apt/sources.list.d` ships with the image, so the prepare step can just write the source list. The unit test creates the directory with `ensurePaths`, mirroring the image layout. Co-Authored-By: Claude Opus 5 <michael.kriese+claude-code@mend.io>
Binds the root only tool into the existing container and mocks the bun service through its prototype, like the surrounding tests already do, so no second container is needed to keep the tool lookups unambiguous. Co-Authored-By: Claude Opus 5 <michael.kriese+claude-code@mend.io>
Writes `etc/apt/sources.list.d/git.sources` in the deb822 format instead of the one line `git.list`, matching how apt sources are written nowadays. Co-Authored-By: Claude Opus 5 <michael.kriese+claude-code@mend.io>
Uses the `codeBlock` tag from common-tags, like the other generated config files in this repo, instead of joining an array of lines. The dedented output has no trailing newline, which matches how the conan profile and the maven settings are written. Co-Authored-By: Claude Opus 5 <michael.kriese+claude-code@mend.io>
Keeps the expected file contents indented with the surrounding test code instead of flush to column zero. Co-Authored-By: Claude Opus 5 <michael.kriese+claude-code@mend.io>
Distributions may append a suffix like `2.55.0-1ubuntu1` to the version git prints, which `dpkg --compare-versions` handled but semver cannot parse. Coerces the output before comparing it with the minimum version, and fails with a clear message when no version can be found at all. Co-Authored-By: Claude Opus 5 <michael.kriese+claude-code@mend.io>
The installed version is already printed by the test step, which runs `git --version`. Co-Authored-By: Claude Opus 5 <michael.kriese+claude-code@mend.io>
The apt package is shared by every recorded git version, so uninstalling one of them would remove the system git while another version is still current and git-lfs still depends on it. Adds a `canUninstall` flag to the install services, which git sets to false, so `uninstall-tool git` reports `NotSupported` like it did before the conversion. Drops the now unused `AptService.remove` again. Co-Authored-By: Claude Opus 5 <michael.kriese+claude-code@mend.io>
Code Review ✅ Approved 1 closed / 1 findings🟡 Medium risk · Adds root-only system-wide Git installation and PPA configuration through the installer. Converts the last v1 shell tool ( ✅ 1 closed✅ Edge Case: Uninstalling any recorded git version removes the system git package
OptionsAuto-apply is off → Gitar will not commit updates to this branch. Comment with these commands to change the behavior for this request:
Important Your trial ends in 2 days — upgrade now to keep code review, CI analysis, auto-apply, custom automations, and more. Was this helpful? React with 👍 / 👎 | Gitar |
Converts
git, the last v1 shell tool, into a TypeScript install service, so every toolinstall-toolaccepts is backed by a service.This is a prerequisite for #6166 / #7435: without a service,
gitcannot appear in the generated tool list, which is also whygit-lfscurrently carries aparentthat consumers can't resolve.The service
src/cli/tools/git/index.tsreplacessrc/usr/local/containerbase/tools/git.sh:GitPrepareServicefetches thegit-coreppa key withHttpServiceand writesetc/apt/keyrings/git.ascplusetc/apt/sources.list.d/git.list, with the codename fromgetDistro()and the architecture fromEnvService. Paths go throughenvSvc.rootDir, the same conventionAptServiceuses, so it is testable.GitInstallServiceinstalls throughAptService, then verifies the installed version is at least 2.33.0 — the minimum Renovate needs — and fails with the same message as the old script.linkis a documented no-op because apt installs system wide,postInstallkeeps thesafe.directoryflutter workaround,testrunsgit --version, anduninstallremoves the package again through a newAptService.remove().Root
git can only be installed as root, and that is now enforced in the cli rather than deep inside apt:
BaseInstallServicegains aneedsRootflag, andInstallToolServicereturns the newNotRootcode from bothinstall()anduninstall()with a clear message. The check runs beforevalidate(), so a permissions problem is no longer reported as "tool version not supported".The v1 and v2 runtime support (
V1ToolInstallService,V2ToolInstallService,bin/v1-install-tool.sh,bin/v2-install-tool.shand the remainingtools/v2/*.sh) is deliberately left in place for compatibility with downstream images; only the git script itself is removed.Verification
pnpm eslint,pnpm lint:types,pnpm lint:markdownand prettier pass.pnpm test:vitest: 569 tests, 100% statements / branches / functions / lines.src/cli/tools/git/index.spec.tscovers prepare (asserting both written files), install, the too-old-version rejection, link, post-install, test and uninstall;install-tool.service.spec.tscovers bothNotRootpaths.pnpm test:docker --network host --allow-host-network -t test-x86_64 latest: thetestcstage, which is the one that exercises this change, installs git and printsgit version 2.55.0, then installs git-lfs on top, and the stage completes.That run then failed later in the unrelated
testestage atinstall-tool apm 0.30.0, because apm's bundled GitPython cannot find a git executable there. That is a local-only artifact:BASE_IMAGEdefaults to thecontainerbasestage built fromghcr.io/containerbase/ubuntu:24.04, which ships no git package (verified withdpkg -l git), while CI pointsBASE_IMAGEat the real base image, which installs git. Nothing in that stage callsinstall-tool git.🤖 Generated with Claude Code
Summary by CodeRabbit