package commands import ( "fmt" "gitlab.com/revalus/grm/internal/config" "os" "github.com/go-git/go-billy/v5" "github.com/go-git/go-billy/v5/osfs" "github.com/go-git/go-git/v5" gitcfg "github.com/go-git/go-git/v5/config" "github.com/go-git/go-git/v5/plumbing/cache" "github.com/go-git/go-git/v5/storage/filesystem" ) type TestSetup struct { rootFS billy.Filesystem baseRepository struct { fileSystem billy.Filesystem repo *git.Repository } } func checkErrorDuringPreparation(err error) { if err != nil { fmt.Printf("Cannot prepare a temporary directory for testing! %v ", err.Error()) os.Exit(2) } } func createTmpDir() string { baseForTMPDir := fmt.Sprintf("%v/grmTest", os.TempDir()) if _, ok := os.Stat(baseForTMPDir); ok != nil { err := os.Mkdir(baseForTMPDir, 0777) checkErrorDuringPreparation(err) } tempDir, err := os.MkdirTemp(baseForTMPDir, "*") checkErrorDuringPreparation(err) return tempDir } func getTestSetup() TestSetup { tmpDir := createTmpDir() baseFileSystem := osfs.New(tmpDir) initRepositoryFileSystem, err := baseFileSystem.Chroot("worktree") checkErrorDuringPreparation(err) directoryForGitMetadata, err := initRepositoryFileSystem.Chroot(".git") checkErrorDuringPreparation(err) repository, err := git.Init(filesystem.NewStorage(directoryForGitMetadata, cache.NewObjectLRUDefault()), initRepositoryFileSystem) checkErrorDuringPreparation(err) fileForFirstCommit, err := initRepositoryFileSystem.Create("TestFile.txt") checkErrorDuringPreparation(err) _, err = fileForFirstCommit.Write([]byte("foo-conent")) checkErrorDuringPreparation(err) repositoryWorkTree, err := repository.Worktree() checkErrorDuringPreparation(err) repositoryWorkTree.Add(fileForFirstCommit.Name()) _, err = repositoryWorkTree.Commit("First commit", &git.CommitOptions{}) checkErrorDuringPreparation(err) return TestSetup{ baseRepository: struct { fileSystem billy.Filesystem repo *git.Repository }{ fileSystem: initRepositoryFileSystem, repo: repository, }, rootFS: baseFileSystem, } } func makeCommit(wk *git.Worktree, commitMessage string) { _, err := wk.Commit(commitMessage, &git.CommitOptions{}) checkErrorDuringPreparation(err) } func getFSForLocalRepo(dirName string, baseFileSystem billy.Filesystem) (billy.Filesystem, *filesystem.Storage) { fsForLocalRepo, err := baseFileSystem.Chroot(dirName) checkErrorDuringPreparation(err) fsForMetadata, err := fsForLocalRepo.Chroot(".git") checkErrorDuringPreparation(err) storageForTestRepo := filesystem.NewStorage(fsForMetadata, cache.NewObjectLRUDefault()) return fsForLocalRepo, storageForTestRepo } func getBaseForTestingSyncCommand() (StatusChecker, *git.Repository, config.RepositoryConfig, TestSetup) { tmpDirWithInitialRepository := getTestSetup() dirNameForLocalRepository := "testRepo" fsForLocalRepo, storageForTestRepo := getFSForLocalRepo(dirNameForLocalRepository, tmpDirWithInitialRepository.rootFS) fakeLocalRepository, err := git.Clone(storageForTestRepo, fsForLocalRepo, &git.CloneOptions{ URL: tmpDirWithInitialRepository.baseRepository.fileSystem.Root(), }) checkErrorDuringPreparation(err) sc := StatusChecker{ workspace: tmpDirWithInitialRepository.rootFS.Root(), } repoCfg := config.RepositoryConfig{ Name: "test", Src: tmpDirWithInitialRepository.baseRepository.fileSystem.Root(), Dest: dirNameForLocalRepository, } return sc, fakeLocalRepository, repoCfg, tmpDirWithInitialRepository } func getBaseForTestingSyncMultipleRemote() (StatusChecker, *git.Repository, config.RepositoryConfig) { sc, fakeLocalRepository, repoCfg, tmpDirWithInitialRepository := getBaseForTestingSyncCommand() fakeLocalRepository.CreateRemote(&gitcfg.RemoteConfig{ Name: "subremote", URLs: []string{tmpDirWithInitialRepository.baseRepository.fileSystem.Root()}, }) fakeLocalRepository.Fetch(&git.FetchOptions{ RemoteName: "subremote", }) return sc, fakeLocalRepository, repoCfg }