added repo bootstrap tool #19

Merged
JMR-dev merged 13 commits from feat-add-repo-bootstrap-tool into main 2026-05-26 20:20:28 +00:00
4 changed files with 116 additions and 10 deletions
Showing only changes of commit 41a6f74ce1 - Show all commits
+2
View File
@@ -164,6 +164,8 @@ 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(),
"webcamoid": skipOverride(),
+10
View File
@@ -84,6 +84,16 @@ func TestResolveSystemPkgs(t *testing.T) {
if len(skipped) != 1 || skipped[0] != "docker-compose" {
t.Errorf("expected skipped to be [docker-compose], got %v", skipped)
}
// brew: bashtop -> btop (replace), buildah -> skipped
pkgMgr = "brew"
resolved, skipped = resolveSystemPkgs([]string{"bashtop", "buildah", "rg"})
if len(resolved) != 2 || resolved[0] != "btop" || resolved[1] != "ripgrep" {
t.Errorf("expected [btop ripgrep], got %v", resolved)
}
if len(skipped) != 1 || skipped[0] != "buildah" {
t.Errorf("expected skipped to be [buildah], got %v", skipped)
}
}
func TestIsSystemPkgInstalled(t *testing.T) {
+19 -8
View File
@@ -389,9 +389,10 @@ func userLoginShell(uid string) string {
func cloneNvimConfig() {
home, _ := os.UserHomeDir()
configDir := filepath.Join(home, ".config", "nvim")
repoURL := "git@github.com:JMR-dev/nvim-config.git"
const sshURL = "git@github.com:JMR-dev/nvim-config.git"
const httpsURL = "https://github.com/JMR-dev/nvim-config.git"
fmt.Printf("\n[Neovim] Setting up configuration from %s ...\n", repoURL)
fmt.Printf("\n[Neovim] Setting up configuration from %s ...\n", sshURL)
if _, err := osStat(configDir); err == nil {
n := 1
@@ -413,14 +414,18 @@ func cloneNvimConfig() {
osMkdirAll(filepath.Dir(configDir), 0o755)
repoName := strings.TrimSuffix(filepath.Base(repoURL), ".git")
repoName := strings.TrimSuffix(filepath.Base(sshURL), ".git")
tempClone := filepath.Join(filepath.Dir(configDir), repoName)
osRemoveAll(tempClone)
fmt.Printf(" Cloning to %s ...\n", configDir)
if !runCmd([]string{"git", "clone", repoURL, tempClone}, CmdOpts{}).OK() {
errLog("Neovim configuration clone failed")
return
if !runCmd([]string{"git", "clone", sshURL, tempClone}, CmdOpts{}).OK() {
fmt.Printf(" SSH clone failed; falling back to HTTPS (%s) ...\n", httpsURL)
osRemoveAll(tempClone)
if !runCmd([]string{"git", "clone", httpsURL, tempClone}, CmdOpts{}).OK() {
errLog("Neovim configuration clone failed")
return
}
}
if tempClone != configDir {
fmt.Printf(" Renaming %s to %s ...\n", filepath.Base(tempClone), filepath.Base(configDir))
@@ -498,8 +503,14 @@ func installPlaywright() {
errLog("playwright installation failed")
return
}
fmt.Println(" Installing Playwright browsers with dependencies ...")
if !runShell(`bash -c "source ~/.nvm/nvm.sh && source ~/.bashrc 2>/dev/null; pnpx playwright install --with-deps"`, CmdOpts{}).OK() {
installCmd := "pnpx playwright install"
if pkgMgr == "apt-get" {
fmt.Println(" Installing Playwright browsers with dependencies ...")
installCmd += " --with-deps"
} else {
fmt.Println(" Installing Playwright browsers ...")
}
if !runShell(fmt.Sprintf(`bash -c "source ~/.nvm/nvm.sh && source ~/.bashrc 2>/dev/null; %s"`, installCmd), CmdOpts{}).OK() {
errLog("playwright browser installation failed")
}
}
+85 -2
View File
@@ -231,6 +231,63 @@ func TestCloneNvimConfig(t *testing.T) {
}
}
func TestCloneNvimConfigSSHFallback(t *testing.T) {
defer resetMocks()
tmp := t.TempDir()
t.Setenv("HOME", tmp)
osStat = func(name string) (os.FileInfo, error) {
return nil, os.ErrNotExist // nothing exists
}
var runCmdCalls [][]string
runCmd = func(argv []string, opts CmdOpts) CmdResult {
runCmdCalls = append(runCmdCalls, argv)
// First clone (SSH) fails; second (HTTPS) succeeds.
if len(runCmdCalls) == 1 {
return CmdResult{ExitCode: 1}
}
return CmdResult{ExitCode: 0}
}
cloneNvimConfig()
if len(runCmdCalls) != 2 {
t.Fatalf("expected 2 git clone attempts (SSH then HTTPS), got: %v", runCmdCalls)
}
if !strings.HasPrefix(runCmdCalls[0][2], "git@github.com:") {
t.Errorf("expected first attempt to use SSH URL, got: %v", runCmdCalls[0])
}
if !strings.HasPrefix(runCmdCalls[1][2], "https://github.com/") {
t.Errorf("expected fallback to use HTTPS URL, got: %v", runCmdCalls[1])
}
if hasErrors() {
t.Errorf("expected no errors logged when HTTPS fallback succeeds")
}
}
func TestCloneNvimConfigBothFail(t *testing.T) {
defer resetMocks()
tmp := t.TempDir()
t.Setenv("HOME", tmp)
osStat = func(name string) (os.FileInfo, error) {
return nil, os.ErrNotExist
}
runCmd = func(argv []string, opts CmdOpts) CmdResult {
return CmdResult{ExitCode: 1}
}
cloneNvimConfig()
if !hasErrors() {
t.Errorf("expected error logged when both SSH and HTTPS clones fail")
}
}
func TestCheckAndSetupSSH(t *testing.T) {
defer resetMocks()
@@ -651,8 +708,9 @@ func TestInstallPlaywright(t *testing.T) {
}
installPlaywright() // should log error and return
// Happy path
// Happy path on apt-get: should pass --with-deps
resetMocks()
pkgMgr = "apt-get"
osStat = func(name string) (os.FileInfo, error) {
return nil, nil // nvm exists
}
@@ -676,7 +734,32 @@ func TestInstallPlaywright(t *testing.T) {
t.Errorf("expected pnpm add -g playwright, got: %v", runShellCmds)
}
if !hasPlaywrightBrowsers {
t.Errorf("expected pnpx playwright install --with-deps, got: %v", runShellCmds)
t.Errorf("expected pnpx playwright install --with-deps on apt-get, got: %v", runShellCmds)
}
// Happy path on non-apt (dnf/pacman/brew): must NOT pass --with-deps
resetMocks()
pkgMgr = "dnf"
osStat = func(name string) (os.FileInfo, error) {
return nil, nil
}
var dnfShellCmds []string
runShell = func(cmd string, opts CmdOpts) CmdResult {
dnfShellCmds = append(dnfShellCmds, cmd)
return CmdResult{ExitCode: 0}
}
installPlaywright()
hasPlainBrowsers := false
for _, cmd := range dnfShellCmds {
if strings.Contains(cmd, "--with-deps") {
t.Errorf("did not expect --with-deps on dnf, got: %v", dnfShellCmds)
}
if strings.Contains(cmd, "pnpx playwright install") {
hasPlainBrowsers = true
}
}
if !hasPlainBrowsers {
t.Errorf("expected pnpx playwright install (without --with-deps) on dnf, got: %v", dnfShellCmds)
}
// Failure path: pnpm install fails, browser install should be skipped