diff --git a/cli/dotfiles.go b/cli/dotfiles.go index 0fbbc25a1e37b..472c4c8a03a99 100644 --- a/cli/dotfiles.go +++ b/cli/dotfiles.go @@ -4,7 +4,6 @@ import ( "bytes" "errors" "fmt" - "io/fs" "os" "os/exec" "path/filepath" @@ -184,7 +183,7 @@ func (r *RootCmd) dotfiles() *serpent.Command { } } - script := findScript(installScriptSet, files) + script := findScript(installScriptSet, dotfilesDir) if script != "" { _, err = cliui.Prompt(inv, cliui.PromptOptions{ Text: fmt.Sprintf("Running install script %s.\n\n Continue?", script), @@ -361,15 +360,12 @@ func dirExists(name string) (bool, error) { } // findScript will find the first file that matches the script set. -func findScript(scriptSet []string, files []fs.DirEntry) string { +func findScript(scriptSet []string, directory string) string { for _, i := range scriptSet { - for _, f := range files { - if f.Name() == i { - return f.Name() - } + if _, err := os.Stat(filepath.Join(directory, i)); err == nil { + return i } } - return "" } diff --git a/cli/dotfiles_test.go b/cli/dotfiles_test.go index 6726f35b785ad..2f16929cc24ff 100644 --- a/cli/dotfiles_test.go +++ b/cli/dotfiles_test.go @@ -142,6 +142,41 @@ func TestDotfiles(t *testing.T) { require.NoError(t, err) require.Equal(t, string(b), "wow\n") }) + + t.Run("NestedInstallScript", func(t *testing.T) { + t.Parallel() + if runtime.GOOS == "windows" { + t.Skip("install scripts on windows require sh and aren't very practical") + } + _, root := clitest.New(t) + testRepo := testGitRepo(t, root) + + scriptPath := filepath.Join("script", "setup") + err := os.MkdirAll(filepath.Join(testRepo, "script"), 0o750) + require.NoError(t, err) + // nolint:gosec + err = os.WriteFile(filepath.Join(testRepo, scriptPath), []byte("#!/bin/bash\necho wow > "+filepath.Join(string(root), ".bashrc")), 0o750) + require.NoError(t, err) + + c := exec.Command("git", "add", scriptPath) + c.Dir = testRepo + err = c.Run() + require.NoError(t, err) + + c = exec.Command("git", "commit", "-m", `"add script"`) + c.Dir = testRepo + err = c.Run() + require.NoError(t, err) + + inv, _ := clitest.New(t, "dotfiles", "--global-config", string(root), "--symlink-dir", string(root), "-y", testRepo) + err = inv.Run() + require.NoError(t, err) + + b, err := os.ReadFile(filepath.Join(string(root), ".bashrc")) + require.NoError(t, err) + require.Equal(t, string(b), "wow\n") + }) + t.Run("InstallScriptChangeBranch", func(t *testing.T) { t.Parallel() if runtime.GOOS == "windows" {