mirror of
https://github.com/coder/coder.git
synced 2025-03-14 10:09:57 +00:00
347 lines
9.9 KiB
Go
347 lines
9.9 KiB
Go
package cli_test
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"runtime"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/coder/coder/v2/cli/clitest"
|
|
"github.com/coder/coder/v2/cli/config"
|
|
"github.com/coder/coder/v2/cryptorand"
|
|
)
|
|
|
|
func TestDotfiles(t *testing.T) {
|
|
t.Parallel()
|
|
// This test will time out if the user has commit signing enabled.
|
|
if _, gpgTTYFound := os.LookupEnv("GPG_TTY"); gpgTTYFound {
|
|
t.Skip("GPG_TTY is set, skipping test to avoid hanging")
|
|
}
|
|
t.Run("MissingArg", func(t *testing.T) {
|
|
t.Parallel()
|
|
inv, _ := clitest.New(t, "dotfiles")
|
|
err := inv.Run()
|
|
require.Error(t, err)
|
|
})
|
|
t.Run("NoInstallScript", func(t *testing.T) {
|
|
t.Parallel()
|
|
_, root := clitest.New(t)
|
|
testRepo := testGitRepo(t, root)
|
|
|
|
// nolint:gosec
|
|
err := os.WriteFile(filepath.Join(testRepo, ".bashrc"), []byte("wow"), 0o750)
|
|
require.NoError(t, err)
|
|
|
|
c := exec.Command("git", "add", ".bashrc")
|
|
c.Dir = testRepo
|
|
err = c.Run()
|
|
require.NoError(t, err)
|
|
|
|
c = exec.Command("git", "commit", "-m", `"add .bashrc"`)
|
|
c.Dir = testRepo
|
|
out, err := c.CombinedOutput()
|
|
require.NoError(t, err, string(out))
|
|
|
|
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")
|
|
})
|
|
t.Run("SwitchRepoDir", func(t *testing.T) {
|
|
t.Parallel()
|
|
_, root := clitest.New(t)
|
|
testRepo := testGitRepo(t, root)
|
|
|
|
// nolint:gosec
|
|
err := os.WriteFile(filepath.Join(testRepo, ".bashrc"), []byte("wow"), 0o750)
|
|
require.NoError(t, err)
|
|
|
|
c := exec.Command("git", "add", ".bashrc")
|
|
c.Dir = testRepo
|
|
err = c.Run()
|
|
require.NoError(t, err)
|
|
|
|
c = exec.Command("git", "commit", "-m", `"add .bashrc"`)
|
|
c.Dir = testRepo
|
|
out, err := c.CombinedOutput()
|
|
require.NoError(t, err, string(out))
|
|
|
|
inv, _ := clitest.New(t, "dotfiles", "--global-config", string(root), "--symlink-dir", string(root), "--repo-dir", "testrepo", "-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")
|
|
|
|
stat, staterr := os.Stat(filepath.Join(string(root), "testrepo"))
|
|
require.NoError(t, staterr)
|
|
require.True(t, stat.IsDir())
|
|
})
|
|
t.Run("SwitchRepoDirRelative", func(t *testing.T) {
|
|
t.Parallel()
|
|
_, root := clitest.New(t)
|
|
testRepo := testGitRepo(t, root)
|
|
|
|
// nolint:gosec
|
|
err := os.WriteFile(filepath.Join(testRepo, ".bashrc"), []byte("wow"), 0o750)
|
|
require.NoError(t, err)
|
|
|
|
c := exec.Command("git", "add", ".bashrc")
|
|
c.Dir = testRepo
|
|
err = c.Run()
|
|
require.NoError(t, err)
|
|
|
|
c = exec.Command("git", "commit", "-m", `"add .bashrc"`)
|
|
c.Dir = testRepo
|
|
out, err := c.CombinedOutput()
|
|
require.NoError(t, err, string(out))
|
|
|
|
inv, _ := clitest.New(t, "dotfiles", "--global-config", string(root), "--symlink-dir", string(root), "--repo-dir", "./relrepo", "-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")
|
|
|
|
stat, staterr := os.Stat(filepath.Join(string(root), "relrepo"))
|
|
require.NoError(t, staterr)
|
|
require.True(t, stat.IsDir())
|
|
})
|
|
t.Run("SymlinkBackup", func(t *testing.T) {
|
|
t.Parallel()
|
|
_, root := clitest.New(t)
|
|
testRepo := testGitRepo(t, root)
|
|
|
|
// nolint:gosec
|
|
err := os.WriteFile(filepath.Join(testRepo, ".bashrc"), []byte("wow"), 0o750)
|
|
require.NoError(t, err)
|
|
|
|
// add a conflicting file at destination
|
|
// nolint:gosec
|
|
err = os.WriteFile(filepath.Join(string(root), ".bashrc"), []byte("backup"), 0o750)
|
|
require.NoError(t, err)
|
|
|
|
c := exec.Command("git", "add", ".bashrc")
|
|
c.Dir = testRepo
|
|
err = c.Run()
|
|
require.NoError(t, err)
|
|
|
|
c = exec.Command("git", "commit", "-m", `"add .bashrc"`)
|
|
c.Dir = testRepo
|
|
out, err := c.CombinedOutput()
|
|
require.NoError(t, err, string(out))
|
|
|
|
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")
|
|
|
|
// check for backup file
|
|
b, err = os.ReadFile(filepath.Join(string(root), ".bashrc.bak"))
|
|
require.NoError(t, err)
|
|
require.Equal(t, string(b), "backup")
|
|
|
|
// check for idempotency
|
|
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")
|
|
b, err = os.ReadFile(filepath.Join(string(root), ".bashrc.bak"))
|
|
require.NoError(t, err)
|
|
require.Equal(t, string(b), "backup")
|
|
})
|
|
}
|
|
|
|
func TestDotfilesInstallScriptUnix(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
if runtime.GOOS == "windows" {
|
|
t.Skip()
|
|
}
|
|
|
|
t.Run("InstallScript", func(t *testing.T) {
|
|
t.Parallel()
|
|
_, root := clitest.New(t)
|
|
testRepo := testGitRepo(t, root)
|
|
|
|
// nolint:gosec
|
|
err := os.WriteFile(filepath.Join(testRepo, "install.sh"), []byte("#!/bin/bash\necho wow > "+filepath.Join(string(root), ".bashrc")), 0o750)
|
|
require.NoError(t, err)
|
|
|
|
c := exec.Command("git", "add", "install.sh")
|
|
c.Dir = testRepo
|
|
err = c.Run()
|
|
require.NoError(t, err)
|
|
|
|
c = exec.Command("git", "commit", "-m", `"add install.sh"`)
|
|
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("NestedInstallScript", func(t *testing.T) {
|
|
t.Parallel()
|
|
_, 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()
|
|
_, root := clitest.New(t)
|
|
testRepo := testGitRepo(t, root)
|
|
|
|
// We need an initial commit to start the `main` branch
|
|
c := exec.Command("git", "commit", "--allow-empty", "-m", `"initial commit"`)
|
|
c.Dir = testRepo
|
|
err := c.Run()
|
|
require.NoError(t, err)
|
|
|
|
// nolint:gosec
|
|
err = os.WriteFile(filepath.Join(testRepo, "install.sh"), []byte("#!/bin/bash\necho wow > "+filepath.Join(string(root), ".bashrc")), 0o750)
|
|
require.NoError(t, err)
|
|
|
|
c = exec.Command("git", "checkout", "-b", "other_branch")
|
|
c.Dir = testRepo
|
|
err = c.Run()
|
|
require.NoError(t, err)
|
|
|
|
c = exec.Command("git", "add", "install.sh")
|
|
c.Dir = testRepo
|
|
err = c.Run()
|
|
require.NoError(t, err)
|
|
|
|
c = exec.Command("git", "commit", "-m", `"add install.sh"`)
|
|
c.Dir = testRepo
|
|
err = c.Run()
|
|
require.NoError(t, err)
|
|
|
|
c = exec.Command("git", "checkout", "main")
|
|
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, "-b", "other_branch")
|
|
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")
|
|
})
|
|
}
|
|
|
|
func TestDotfilesInstallScriptWindows(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
if runtime.GOOS != "windows" {
|
|
t.Skip()
|
|
}
|
|
|
|
t.Run("InstallScript", func(t *testing.T) {
|
|
t.Parallel()
|
|
_, root := clitest.New(t)
|
|
testRepo := testGitRepo(t, root)
|
|
|
|
// nolint:gosec
|
|
err := os.WriteFile(filepath.Join(testRepo, "install.ps1"), []byte("echo \"hello, computer!\" > "+filepath.Join(string(root), "greeting.txt")), 0o750)
|
|
require.NoError(t, err)
|
|
|
|
c := exec.Command("git", "add", "install.ps1")
|
|
c.Dir = testRepo
|
|
err = c.Run()
|
|
require.NoError(t, err)
|
|
|
|
c = exec.Command("git", "commit", "-m", `"add install.ps1"`)
|
|
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), "greeting.txt"))
|
|
require.NoError(t, err)
|
|
// If you squint, it does in fact say "hello, computer!" in here, but in
|
|
// UTF-16 and with a byte-order-marker at the beginning. Windows!
|
|
require.Equal(t, b, []byte("\xff\xfeh\x00e\x00l\x00l\x00o\x00,\x00 \x00c\x00o\x00m\x00p\x00u\x00t\x00e\x00r\x00!\x00\r\x00\n\x00"))
|
|
})
|
|
}
|
|
|
|
func testGitRepo(t *testing.T, root config.Root) string {
|
|
r, err := cryptorand.String(8)
|
|
require.NoError(t, err)
|
|
dir := filepath.Join(string(root), fmt.Sprintf("test-repo-%s", r))
|
|
err = os.MkdirAll(dir, 0o750)
|
|
require.NoError(t, err)
|
|
|
|
c := exec.Command("git", "init")
|
|
c.Dir = dir
|
|
err = c.Run()
|
|
require.NoError(t, err)
|
|
|
|
c = exec.Command("git", "config", "user.email", "ci@coder.com")
|
|
c.Dir = dir
|
|
err = c.Run()
|
|
require.NoError(t, err)
|
|
|
|
c = exec.Command("git", "config", "user.name", "C I")
|
|
c.Dir = dir
|
|
err = c.Run()
|
|
require.NoError(t, err)
|
|
|
|
c = exec.Command("git", "checkout", "-b", "main")
|
|
c.Dir = dir
|
|
err = c.Run()
|
|
require.NoError(t, err)
|
|
|
|
return dir
|
|
}
|