gitlab.com/pidrakin/dotfiles-cli@v1.7.5/cmd/link/link_test.go (about) 1 package link 2 3 import ( 4 "bytes" 5 "crypto/md5" 6 "encoding/hex" 7 "os" 8 "path" 9 "path/filepath" 10 "testing" 11 "time" 12 13 "github.com/go-git/go-git/v5" 14 "github.com/go-git/go-git/v5/plumbing/object" 15 "github.com/mitchellh/go-homedir" 16 log "github.com/sirupsen/logrus" 17 "github.com/stretchr/testify/assert" 18 "gitlab.com/pidrakin/dotfiles-cli/cmd/initialize" 19 "gitlab.com/pidrakin/dotfiles-cli/cmd/install" 20 "gitlab.com/pidrakin/go/sysfs" 21 "gitlab.com/pidrakin/go/tests" 22 ) 23 24 var ( 25 repoPath = "repository" 26 repoExpertPath = "repository-expert" 27 clonedRepo = "clone" 28 clonedExpertRepo = "clone-expert" 29 homeDir = "home/user" 30 ) 31 32 func init() { 33 homedir.DisableCache = true 34 } 35 36 func setupRepo(t *testing.T, wd string, path string, cloned string, expert bool) { 37 log.SetLevel(log.FatalLevel) 38 39 repo := filepath.Join(wd, path) 40 err := os.MkdirAll(repo, os.FileMode(0755)) 41 tests.AssertNoError(t, err) 42 43 err = os.Chdir(filepath.Join(wd, path)) 44 tests.AssertNoError(t, err) 45 46 err = initialize.Run(expert, true) 47 tests.AssertNoError(t, err) 48 49 _, err = git.PlainInit(repo, false) 50 tests.AssertNoError(t, err) 51 52 r, err := git.PlainOpen(repo) 53 tests.AssertNoError(t, err) 54 55 w, err := r.Worktree() 56 tests.AssertNoError(t, err) 57 58 _, err = w.Add(".") 59 tests.AssertNoError(t, err) 60 61 status, err := w.Status() 62 tests.AssertNoError(t, err) 63 assert.NotEmpty(t, status) 64 65 commit, err := w.Commit("example go-git commit", &git.CommitOptions{ 66 Author: &object.Signature{ 67 Name: "John Doe", 68 Email: "john@doe.org", 69 When: time.Now(), 70 }, 71 }) 72 tests.AssertNoError(t, err) 73 74 obj, err := r.CommitObject(commit) 75 tests.AssertNoError(t, err) 76 assert.NotEmpty(t, obj) 77 78 err = os.Chdir(wd) 79 tests.AssertNoError(t, err) 80 81 var buf bytes.Buffer 82 _, err = git.PlainClone(cloned, false, &git.CloneOptions{ 83 URL: path, 84 Progress: &buf, 85 }) 86 tests.AssertNoError(t, err) 87 assert.NotEmpty(t, buf.String()) 88 } 89 90 func installRepo(t *testing.T, wd string, path string) { 91 err := os.Setenv("HOME", filepath.Join(wd, homeDir)) 92 tests.AssertNoError(t, err) 93 94 err = install.Run(false, false, filepath.Join(wd, path)) 95 tests.AssertNoError(t, err) 96 } 97 98 func linkRepo(t *testing.T, collection string) { 99 runHooks := true 100 err := Run(false, false, false, &runHooks, collection) 101 tests.AssertNoError(t, err) 102 } 103 104 func TestLinker_LinkSimple(t *testing.T) { 105 tests.RunInTmp(t, func(t *testing.T, wd string) { 106 setupRepo(t, wd, repoPath, clonedRepo, false) 107 installRepo(t, wd, clonedRepo) 108 linkRepo(t, "") 109 110 files := []string{ 111 ".bashrc", 112 ".profile", 113 } 114 115 for _, entry := range files { 116 target := path.Join(wd, homeDir, entry) 117 tests.AssertFileExists(t, target) 118 source, err := sysfs.ReadLink(target) 119 tests.AssertNoError(t, err) 120 121 dotfilesDir := path.Join(wd, homeDir, ".local/share/dotfiles") 122 tests.AssertDirExists(t, dotfilesDir) 123 sum := md5.Sum([]byte(path.Join(wd, clonedRepo))) 124 context := hex.EncodeToString(sum[:]) 125 installDir := filepath.Join(dotfilesDir, context) 126 127 expected := path.Join(installDir, entry) 128 assert.Equalf(t, expected, source, "expected link [%s] to point to [%s] but got [%s]", target, expected, source) 129 } 130 }) 131 } 132 133 func TestLinker_LinkExpert(t *testing.T) { 134 tests.RunInTmp(t, func(t *testing.T, wd string) { 135 setupRepo(t, wd, repoPath, clonedRepo, true) 136 installRepo(t, wd, clonedRepo) 137 linkRepo(t, "mac") 138 139 files := [][]string{ 140 {"vim", ".vimrc"}, 141 {"tmux", ".tmux.conf"}, 142 } 143 144 for _, entry := range files { 145 target := path.Join(wd, homeDir, entry[1]) 146 tests.AssertFileExists(t, target) 147 source, err := sysfs.ReadLink(target) 148 tests.AssertNoError(t, err) 149 150 dotfilesDir := path.Join(wd, homeDir, ".local/share/dotfiles") 151 tests.AssertDirExists(t, dotfilesDir) 152 sum := md5.Sum([]byte(path.Join(wd, clonedRepo))) 153 context := hex.EncodeToString(sum[:]) 154 installDir := filepath.Join(dotfilesDir, context) 155 156 expected := path.Join(installDir, entry[0], entry[1]) 157 assert.Equalf(t, expected, source, "expected link [%s] to point to [%s] but got [%s]", target, expected, source) 158 } 159 }) 160 } 161 162 func TestLinker_ReLinkSimple(t *testing.T) { 163 tests.RunInTmp(t, func(t *testing.T, wd string) { 164 setupRepo(t, wd, repoPath, clonedRepo, false) 165 installRepo(t, wd, clonedRepo) 166 linkRepo(t, "") 167 linkRepo(t, "") 168 169 files := []string{ 170 ".bashrc", 171 ".profile", 172 } 173 174 for _, entry := range files { 175 target := path.Join(wd, homeDir, entry) 176 tests.AssertFileExists(t, target) 177 source, err := sysfs.ReadLink(target) 178 tests.AssertNoError(t, err) 179 180 dotfilesDir := path.Join(wd, homeDir, ".local/share/dotfiles") 181 tests.AssertDirExists(t, dotfilesDir) 182 sum := md5.Sum([]byte(path.Join(wd, clonedRepo))) 183 context := hex.EncodeToString(sum[:]) 184 installDir := filepath.Join(dotfilesDir, context) 185 186 expected := path.Join(installDir, entry) 187 assert.Equalf(t, expected, source, "expected link [%s] to point to [%s] but got [%s]", target, expected, source) 188 } 189 }) 190 } 191 192 func TestLinker_ReLinkExpert(t *testing.T) { 193 tests.RunInTmp(t, func(t *testing.T, wd string) { 194 setupRepo(t, wd, repoPath, clonedRepo, true) 195 installRepo(t, wd, clonedRepo) 196 linkRepo(t, "mac") 197 linkRepo(t, "mac") 198 199 files := [][]string{ 200 {"vim", ".vimrc"}, 201 {"tmux", ".tmux.conf"}, 202 } 203 204 for _, entry := range files { 205 target := path.Join(wd, homeDir, entry[1]) 206 tests.AssertFileExists(t, target) 207 source, err := sysfs.ReadLink(target) 208 tests.AssertNoError(t, err) 209 210 dotfilesDir := path.Join(wd, homeDir, ".local/share/dotfiles") 211 tests.AssertDirExists(t, dotfilesDir) 212 sum := md5.Sum([]byte(path.Join(wd, clonedRepo))) 213 context := hex.EncodeToString(sum[:]) 214 installDir := filepath.Join(dotfilesDir, context) 215 216 expected := path.Join(installDir, entry[0], entry[1]) 217 assert.Equalf(t, expected, source, "expected link [%s] to point to [%s] but got [%s]", target, expected, source) 218 } 219 }) 220 } 221 222 func TestLinker_ReLinkSimpleExpert(t *testing.T) { 223 tests.RunInTmp(t, func(t *testing.T, wd string) { 224 setupRepo(t, wd, repoPath, clonedRepo, false) 225 installRepo(t, wd, clonedRepo) 226 linkRepo(t, "") 227 setupRepo(t, wd, repoExpertPath, clonedExpertRepo, true) 228 installRepo(t, wd, clonedExpertRepo) 229 linkRepo(t, "mac") 230 231 dotfilesDir := path.Join(wd, homeDir, ".local/share/dotfiles") 232 tests.AssertDirExists(t, dotfilesDir) 233 234 simpleSum := md5.Sum([]byte(path.Join(wd, clonedRepo))) 235 simpleContext := hex.EncodeToString(simpleSum[:]) 236 simpleInstallDir := filepath.Join(dotfilesDir, simpleContext) 237 238 expertSum := md5.Sum([]byte(path.Join(wd, clonedExpertRepo))) 239 expertContext := hex.EncodeToString(expertSum[:]) 240 expertInstallDir := filepath.Join(dotfilesDir, expertContext) 241 242 files := [][]string{ 243 {expertInstallDir, "vim", ".vimrc"}, 244 {expertInstallDir, "tmux", ".tmux.conf"}, 245 {simpleInstallDir, ".bashrc"}, 246 {simpleInstallDir, ".profile"}, 247 } 248 249 for _, entry := range files { 250 target := path.Join(wd, homeDir, entry[len(entry)-1]) 251 tests.AssertFileExists(t, target) 252 source, err := sysfs.ReadLink(target) 253 tests.AssertNoError(t, err) 254 255 expected := path.Join(entry...) 256 assert.Equalf(t, expected, source, "expected link [%s] to point to [%s] but got [%s]", target, expected, source) 257 } 258 }) 259 }