From c4f7f6d240107835469000e45918a4adeefcfaca Mon Sep 17 00:00:00 2001 From: Jason Ross Date: Fri, 29 May 2026 17:59:11 -0500 Subject: [PATCH] package changes --- custom.go | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++ detect.go | 11 +++++++++ packages.go | 43 +++++++++++++++++++++++++++++++++- pkgmgr.go | 21 ++++++++++++++++- system.go | 44 +++++++++++------------------------ 5 files changed, 154 insertions(+), 32 deletions(-) diff --git a/custom.go b/custom.go index f92d8f9..738b909 100644 --- a/custom.go +++ b/custom.go @@ -321,6 +321,48 @@ func installNeovim(_ *CustomPackage, tmp string) { taskPrintf(" Neovim installed to %s, symlinked at %s\n", installDir, symlink) } +func installRustup(archive string) { + out := taskOut() + runCmd([]string{"chmod", "+x", archive}, CmdOpts{Out: out}) + runCmd([]string{archive, "-y", "--no-modify-path"}, CmdOpts{Out: out}) + taskPrintln(" rustup installed.") +} + +func installYq(archive string) { + out := taskOut() + runCmd([]string{"cp", archive, "/usr/local/bin/yq"}, CmdOpts{AsSudo: true, Out: out}) + runCmd([]string{"chmod", "+x", "/usr/local/bin/yq"}, CmdOpts{AsSudo: true, Out: out}) + taskPrintln(" yq installed.") +} + +func installDagger(archive, tmp string) { + out := taskOut() + runCmd([]string{"tar", "-C", tmp, "-xzf", archive}, CmdOpts{Out: out}) + runCmd([]string{"mv", filepath.Join(tmp, "dagger"), "/usr/local/bin/dagger"}, CmdOpts{AsSudo: true, Out: out}) + taskPrintln(" dagger installed.") +} + +func installTrivy(archive, tmp string) { + out := taskOut() + runCmd([]string{"tar", "-C", tmp, "-xzf", archive}, CmdOpts{Out: out}) + runCmd([]string{"mv", filepath.Join(tmp, "trivy"), "/usr/local/bin/trivy"}, CmdOpts{AsSudo: true, Out: out}) + taskPrintln(" trivy installed.") +} + +func installCosign(archive string) { + out := taskOut() + runCmd([]string{"cp", archive, "/usr/local/bin/cosign"}, CmdOpts{AsSudo: true, Out: out}) + runCmd([]string{"chmod", "+x", "/usr/local/bin/cosign"}, CmdOpts{AsSudo: true, Out: out}) + taskPrintln(" cosign installed.") +} + +func installGitleaks(archive, tmp string) { + out := taskOut() + runCmd([]string{"tar", "-C", tmp, "-xzf", archive}, CmdOpts{Out: out}) + runCmd([]string{"mv", filepath.Join(tmp, "gitleaks"), "/usr/local/bin/gitleaks"}, CmdOpts{AsSudo: true, Out: out}) + taskPrintln(" gitleaks installed.") +} + // ── latest-version resolvers ──────────────────────────────────────────── func resolveLatestGo(_ *CustomPackage) (string, string, bool) { @@ -434,10 +476,23 @@ func cmpSemver(a, b string) int { return len(pa) - len(pb) } +func resolveLatestYq(_ *CustomPackage) (string, string, bool) { + var rel ghRelease + if !fetchJSON("https://api.github.com/repos/mikefarah/yq/releases/latest", &rel) { + return "", "", false + } + version := strings.TrimPrefix(rel.TagName, "v") + if version == "" { + return "", "", false + } + return version, "", true +} + var latestResolvers = map[string]func(*CustomPackage) (string, string, bool){ "go": resolveLatestGo, "firecracker": resolveLatestFirecracker, "zig": resolveLatestZig, + "yq": resolveLatestYq, } // resolveLatest best-effort upgrades pkg.Version/SHA256 to the latest release. @@ -598,6 +653,18 @@ func runOneCustomInstall(pkg *CustomPackage) { installFirecracker(archive, tmp) case "zig": installZig(pkg, archive) + case "rustup": + installRustup(archive) + case "yq": + installYq(archive) + case "dagger": + installDagger(archive, tmp) + case "trivy": + installTrivy(archive, tmp) + case "cosign": + installCosign(archive) + case "gitleaks": + installGitleaks(archive, tmp) default: warn(fmt.Sprintf("No install handler for '%s' — skipping", pkg.Name)) } diff --git a/detect.go b/detect.go index 43868e7..e13f677 100644 --- a/detect.go +++ b/detect.go @@ -64,6 +64,12 @@ var ( osZig = map[string]string{"linux": "linux", "macos": "macos"} osNvim = map[string]string{"linux": "linux", "macos": "macos"} + osRustup = map[string]string{"linux": "unknown-linux-gnu", "macos": "apple-darwin"} + archRustup = map[string]string{"x86_64": "x86_64", "aarch64": "aarch64"} + osTrivy = map[string]string{"linux": "Linux", "macos": "macOS"} + archTrivy = map[string]string{"x86_64": "64bit", "aarch64": "ARM64"} + archGitleaks = map[string]string{"x86_64": "x64", "aarch64": "arm64"} + archTokens = map[string][]string{ "x86_64": {"x86_64", "amd64", "x64"}, "aarch64": {"aarch64", "arm64"}, @@ -81,6 +87,11 @@ func formatURL(template, version string) string { "{os_go}", osGo[osName], "{os_zig}", osZig[osName], "{os_nvim}", osNvim[osName], + "{os_rustup}", osRustup[osName], + "{arch_rustup}", archRustup[archName], + "{os_trivy}", osTrivy[osName], + "{arch_trivy}", archTrivy[archName], + "{arch_gitleaks}", archGitleaks[archName], ) return r.Replace(template) } diff --git a/packages.go b/packages.go index ac1e3e0..a3adf44 100644 --- a/packages.go +++ b/packages.go @@ -10,10 +10,11 @@ package main // URL templates use the substitutions described in formatURL. var SystemPackages = []string{ + "age", "ansible", "ansible-core", "aria2", - "bashtop", + "btm", "build-essential", "buildah", "containerd.io", @@ -29,10 +30,14 @@ var SystemPackages = []string{ "git", "github-desktop", "google-chrome-stable", + "helm", + "jq", + "kubectl", "lazygit", "lua", "minisign", "minikube", + "nmap", "obs-studio", "obsidian", "pipx", @@ -42,8 +47,11 @@ var SystemPackages = []string{ "qemu", "restic", "rg", + "semgrep", "shutter", + "sops", "temurin-25-jdk", + "tmux", "vagrant", "virt-manager", "vivaldi-stable", @@ -52,6 +60,8 @@ var SystemPackages = []string{ "yt-dlp", "zoom", "zsh", + "fzf", + "fd", "bzip2", "bzip2-devel", "curl", @@ -142,5 +152,36 @@ func customPackages() []CustomPackage { {Name: "copilot"}, {Name: "playwright"}, {Name: "gh-repo-bootstrap"}, + { + Name: "rustup", + Version: "latest", + URLTemplate: "https://static.rust-lang.org/rustup/dist/{arch_rustup}-{os_rustup}/rustup-init", + }, + { + Name: "yq", + Version: "4.44.1", + URLTemplate: "https://github.com/mikefarah/yq/releases/download/v{version}/yq_{os_go}_{arch_go}", + FetchLatest: "yq", + }, + { + Name: "dagger", + Version: "0.11.4", + URLTemplate: "https://github.com/dagger/dagger/releases/download/v{version}/dagger_v{version}_{os_go}_{arch_go}.tar.gz", + }, + { + Name: "trivy", + Version: "0.52.0", + URLTemplate: "https://github.com/aquasecurity/trivy/releases/download/v{version}/trivy_{version}_{os_trivy}-{arch_trivy}.tar.gz", + }, + { + Name: "cosign", + Version: "2.2.4", + URLTemplate: "https://github.com/sigstore/cosign/releases/download/v{version}/cosign-{os_go}-{arch_go}", + }, + { + Name: "gitleaks", + Version: "8.18.2", + URLTemplate: "https://github.com/gitleaks/gitleaks/releases/download/v{version}/gitleaks_{version}_{os_go}_{arch_gitleaks}.tar.gz", + }, } } diff --git a/pkgmgr.go b/pkgmgr.go index 3b840a3..6f4fcb2 100644 --- a/pkgmgr.go +++ b/pkgmgr.go @@ -77,6 +77,7 @@ var packageOverrides = map[string]map[string]overrideEntry{ "webcamoid": skipOverride(), }, "apt-get": { + "fd": replace("fd-find"), "ffmpeg-free": replace("ffmpeg"), "lua": replace("lua5.4"), "qemu": replace("qemu-system"), @@ -165,7 +166,6 @@ var packageOverrides = map[string]map[string]overrideEntry{ "rg": replace("ripgrep"), "temurin-25-jdk": replace("temurin"), "vivaldi-stable": replace("vivaldi"), - "bashtop": replace("btop"), "buildah": skipOverride(), "shutter": skipOverride(), "virt-manager": skipOverride(), @@ -223,6 +223,25 @@ func resolveSystemPkgs(names []string) ([]string, []string) { return resolved, skipped } +func installSystemPackages(pkgs []string, special []string) { + if len(special) > 0 { + tmp, err := os.MkdirTemp("", "bootstrap-special-") + if err != nil { + errLog(fmt.Sprintf("could not create temp dir for special packages: %v", err)) + return + } + defer osRemoveAll(tmp) + for _, pkg := range special { + fmt.Printf("\n [SPECIAL] Installing %s ...\n", pkg) + installSpecialPkg(pkg, tmp) + } + } + + if pkgMgr == "apt-get" && hasCmd("fdfind") { + runCmd([]string{"ln", "-sf", "/usr/bin/fdfind", "/usr/local/bin/fd"}, CmdOpts{AsSudo: true}) + } +} + // isSystemPkgInstalled queries the host package manager. func isSystemPkgInstalled(pkg string) bool { switch pkgMgr { diff --git a/system.go b/system.go index 16e950c..7b2e356 100644 --- a/system.go +++ b/system.go @@ -16,8 +16,8 @@ func specialPkgs() map[string]bool { } return map[string]bool{ "github-desktop": true, "zoom": true, "obsidian": true, - "minikube": true, "bashtop": true, "pipx": true, - "poetry": true, "pulumi": true, + "minikube": true, "pipx": true, + "poetry": true, "pulumi": true, "semgrep": true, } } @@ -44,14 +44,14 @@ func isSpecialPkgInstalled(pkg string) bool { return exists("/usr/local/bin/obsidian") case "minikube": return exists("/usr/local/bin/minikube") || hasCmd("minikube") - case "bashtop": - return exists("/usr/local/bin/bashtop") || exists(filepath.Join(home, "bashtop")) case "pulumi": return exists("/opt/pulumi/pulumi") || hasCmd("pulumi") case "pipx": return hasCmd("pipx") case "poetry": return hasCmd("poetry") + case "semgrep": + return hasCmd("semgrep") } return isSystemPkgInstalled(pkg) } @@ -259,30 +259,6 @@ func installMinikube(tmp string) { fmt.Printf(" minikube installed to %s\n", installPath) } -func installBashtop(_ string) { - home, _ := os.UserHomeDir() - cloneDir := filepath.Join(home, "bashtop") - if _, err := osStat(cloneDir); err == nil { - fmt.Printf(" Updating existing clone at %s ...\n", cloneDir) - if !runCmd([]string{"git", "-C", cloneDir, "pull"}, CmdOpts{}).OK() { - errLog("bashtop git pull failed") - return - } - } else { - fmt.Printf(" Cloning bashtop to %s ...\n", cloneDir) - if !runCmd([]string{"git", "clone", "https://github.com/aristocratos/bashtop.git", cloneDir}, CmdOpts{}).OK() { - errLog("bashtop git clone failed") - return - } - } - if !runCmd([]string{"make", "install"}, CmdOpts{AsSudo: true, Cwd: cloneDir}).OK() { - errLog("bashtop 'make install' failed") - return - } - appendProfileLine("bashtop", "export PATH=$PATH:"+cloneDir) - fmt.Printf(" bashtop installed. Clone at %s, binary at /usr/local/bin/bashtop\n", cloneDir) -} - func installPulumi(tmp string) { version := fetchText("https://www.pulumi.com/latest-version") if version == "" { @@ -356,6 +332,14 @@ func installPoetry(_ string) { runCmd([]string{"pipx", "install", "poetry"}, CmdOpts{}) } +func installSemgrep(_ string) { + if !hasCmd("pipx") { + errLog("pipx is not installed — cannot install semgrep") + return + } + runCmd([]string{"pipx", "install", "semgrep"}, CmdOpts{}) +} + func installSpecialPkg(pkg, tmp string) { switch pkg { case "github-desktop": @@ -366,14 +350,14 @@ func installSpecialPkg(pkg, tmp string) { installObsidian(tmp) case "minikube": installMinikube(tmp) - case "bashtop": - installBashtop(tmp) case "pulumi": installPulumi(tmp) case "pipx": installPipx(tmp) case "poetry": installPoetry(tmp) + case "semgrep": + installSemgrep(tmp) } }