package core_test import ( "io" "os" "path/filepath" "testing" "time" "git.hrafn.xyz/aether/gosick/internal/homesick/core" git "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/config" "github.com/go-git/go-git/v5/plumbing/object" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" ) type CloneSuite struct { suite.Suite tmpDir string homeDir string reposDir string app *core.App } func TestCloneSuite(t *testing.T) { suite.Run(t, new(CloneSuite)) } func (s *CloneSuite) SetupTest() { s.tmpDir = s.T().TempDir() s.homeDir = filepath.Join(s.tmpDir, "home") s.reposDir = filepath.Join(s.homeDir, ".homesick", "repos") require.NoError(s.T(), os.MkdirAll(s.reposDir, 0o755)) s.app = &core.App{ HomeDir: s.homeDir, ReposDir: s.reposDir, Stdout: io.Discard, Stderr: io.Discard, } } func (s *CloneSuite) createBareRemote(name string) string { remotePath := filepath.Join(s.tmpDir, name+".git") _, err := git.PlainInit(remotePath, true) require.NoError(s.T(), err) workPath := filepath.Join(s.tmpDir, name+"-work") repo, err := git.PlainInit(workPath, false) require.NoError(s.T(), err) castleFile := filepath.Join(workPath, "home", ".vimrc") require.NoError(s.T(), os.MkdirAll(filepath.Dir(castleFile), 0o755)) require.NoError(s.T(), os.WriteFile(castleFile, []byte("set number\n"), 0o644)) wt, err := repo.Worktree() require.NoError(s.T(), err) _, err = wt.Add("home/.vimrc") require.NoError(s.T(), err) _, err = wt.Commit("initial", &git.CommitOptions{Author: &object.Signature{ Name: "Behavior Test", Email: "behavior@test.local", When: time.Now(), }}) require.NoError(s.T(), err) _, err = repo.CreateRemote(&config.RemoteConfig{Name: "origin", URLs: []string{remotePath}}) require.NoError(s.T(), err) require.NoError(s.T(), repo.Push(&git.PushOptions{RemoteName: "origin"})) return remotePath } func (s *CloneSuite) TestClone_FileURLWorksWithoutGitInPath() { remotePath := s.createBareRemote("castle") s.T().Setenv("PATH", "") err := s.app.Clone("file://"+remotePath, "parity-castle") require.NoError(s.T(), err) require.FileExists(s.T(), filepath.Join(s.reposDir, "parity-castle", "home", ".vimrc")) } func (s *CloneSuite) TestClone_DerivesDestinationWhenMissing() { remotePath := s.createBareRemote("dotfiles") err := s.app.Clone("file://"+remotePath, "") require.NoError(s.T(), err) require.DirExists(s.T(), filepath.Join(s.reposDir, "dotfiles")) } func (s *CloneSuite) TestClone_LocalPathSymlinksDirectory() { localCastle := filepath.Join(s.tmpDir, "local-castle") require.NoError(s.T(), os.MkdirAll(filepath.Join(localCastle, "home"), 0o755)) err := s.app.Clone(localCastle, "") require.NoError(s.T(), err) destination := filepath.Join(s.reposDir, "local-castle") info, err := os.Lstat(destination) require.NoError(s.T(), err) require.True(s.T(), info.Mode()&os.ModeSymlink != 0) }