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  }