Skip to content

Commit

Permalink
Add init test (#419)
Browse files Browse the repository at this point in the history
Add init test
  • Loading branch information
twpayne committed Sep 7, 2019
2 parents 6ccd08c + 085c025 commit 283d98e
Show file tree
Hide file tree
Showing 43 changed files with 234 additions and 85 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ script:
- make lint
- make coverage.out
- go run . --version
- GOOS=windows go build .
- if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then goveralls -coverprofile=coverage.out -service=travis-ci -repotoken $COVERALLS_TOKEN; fi

sudo: false
Expand Down
2 changes: 1 addition & 1 deletion cmd/cd_posix.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,5 @@ func (c *Config) runCDCmd(fs vfs.FS, args []string) error {
return err
}

return c.exec([]string{shell})
return c.exec(fs, []string{shell})
}
2 changes: 1 addition & 1 deletion cmd/cd_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ func (c *Config) runCDCmd(fs vfs.FS, args []string) error {
return err
}

return c.run(c.SourceDir, shell)
return c.run(fs, c.SourceDir, shell)
}
24 changes: 15 additions & 9 deletions cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,8 @@ func (c *Config) ensureSourceDirectory(fs chezmoi.PrivacyStater, mutator chezmoi
}
}

func (c *Config) execEditor(argv ...string) error {
return c.exec(append([]string{c.getEditor()}, argv...))
func (c *Config) execEditor(fs vfs.FS, argv ...string) error {
return c.exec(fs, append([]string{c.getEditor()}, argv...))
}

func (c *Config) getDefaultMutator(fs vfs.FS) chezmoi.Mutator {
Expand Down Expand Up @@ -278,12 +278,12 @@ func (c *Config) getTargetState(fs vfs.FS, populateOptions *chezmoi.PopulateOpti
return ts, nil
}

func (c *Config) getVCSInfo() (*vcsInfo, error) {
vcsInfo, ok := vcsInfos[filepath.Base(c.SourceVCS.Command)]
func (c *Config) getVCS() (VCS, error) {
vcs, ok := vcses[filepath.Base(c.SourceVCS.Command)]
if !ok {
return nil, fmt.Errorf("%s: unsupported source VCS command", c.SourceVCS.Command)
}
return vcsInfo, nil
return vcs, nil
}

//nolint:unparam
Expand All @@ -306,7 +306,7 @@ func (c *Config) prompt(s, choices string) (byte, error) {
}

// run runs name argv... in dir.
func (c *Config) run(dir, name string, argv ...string) error {
func (c *Config) run(fs vfs.FS, dir, name string, argv ...string) error {
if c.Verbose {
if dir == "" {
fmt.Printf("%s %s\n", name, strings.Join(argv, " "))
Expand All @@ -318,15 +318,21 @@ func (c *Config) run(dir, name string, argv ...string) error {
return nil
}
cmd := exec.Command(name, argv...)
cmd.Dir = dir
if dir != "" {
var err error
cmd.Dir, err = fs.RawPath(dir)
if err != nil {
return err
}
}
cmd.Stdin = c.Stdin()
cmd.Stdout = c.Stdout()
cmd.Stderr = c.Stdout()
return cmd.Run()
}

func (c *Config) runEditor(argv ...string) error {
return c.run("", c.getEditor(), argv...)
func (c *Config) runEditor(fs vfs.FS, argv ...string) error {
return c.run(fs, "", c.getEditor(), argv...)
}

func (c *Config) warn(s string) {
Expand Down
4 changes: 3 additions & 1 deletion cmd/config_posix.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ import (
"os/exec"
"strings"
"syscall"

vfs "github.com/twpayne/go-vfs"
)

func (c *Config) exec(argv []string) error {
func (c *Config) exec(fs vfs.FS, argv []string) error {
path, err := exec.LookPath(argv[0])
if err != nil {
return err
Expand Down
6 changes: 4 additions & 2 deletions cmd/config_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

package cmd

import vfs "github.com/twpayne/go-vfs"

// exec, on windows, calls run since legit exec doesn't really exist.
func (c *Config) exec(argv []string) error {
return c.run("", argv[0], argv[1:]...)
func (c *Config) exec(fs vfs.FS, argv []string) error {
return c.run(fs, "", argv[0], argv[1:]...)
}
6 changes: 3 additions & 3 deletions cmd/doctor.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,12 @@ func init() {

func (c *Config) runDoctorCmd(fs vfs.FS, args []string) error {
var vcsCommandCheck doctorCheck
if vcsInfo, err := c.getVCSInfo(); err == nil {
if vcs, err := c.getVCS(); err == nil {
vcsCommandCheck = &doctorBinaryCheck{
name: "source VCS command",
binaryName: c.SourceVCS.Command,
versionArgs: vcsInfo.versionArgs,
versionRegexp: vcsInfo.versionRegexp,
versionArgs: vcs.VersionArgs(),
versionRegexp: vcs.VersionRegexp(),
}
} else {
c.warn(fmt.Sprintf("%s: unsupported VCS command", c.SourceVCS.Command))
Expand Down
6 changes: 3 additions & 3 deletions cmd/edit.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func (c *Config) runEditCmd(fs vfs.FS, args []string) error {
if c.edit.prompt {
c.warn("--prompt is currently ignored when edit is run with no arguments")
}
return c.execEditor(c.SourceDir)
return c.execEditor(fs, c.SourceDir)
}

if c.edit.prompt {
Expand Down Expand Up @@ -97,7 +97,7 @@ func (c *Config) runEditCmd(fs vfs.FS, args []string) error {
// Short path: if no post-edit actions are required then exec the editor
// directly.
if !c.edit.diff && !c.edit.apply && len(encryptedFiles) == 0 {
return c.execEditor(argv...)
return c.execEditor(fs, argv...)
}

// If any of the files are encrypted, create a temporary directory to store
Expand Down Expand Up @@ -126,7 +126,7 @@ func (c *Config) runEditCmd(fs vfs.FS, args []string) error {
}
}

if err := c.runEditor(argv...); err != nil {
if err := c.runEditor(fs, argv...); err != nil {
return err
}

Expand Down
2 changes: 1 addition & 1 deletion cmd/editconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func (c *Config) runEditConfigCmd(fs vfs.FS, args []string) error {
}
}

if err := c.runEditor(c.configFile); err != nil {
if err := c.runEditor(fs, c.configFile); err != nil {
return err
}

Expand Down
27 changes: 27 additions & 0 deletions cmd/gitvcs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package cmd

import "regexp"

var gitVersionRegexp = regexp.MustCompile(`^git version (\d+\.\d+\.\d+)`)

type gitVCS struct{}

func (gitVCS) CloneArgs(repo, dir string) []string {
return []string{"clone", repo, dir}
}

func (gitVCS) InitArgs() []string {
return []string{"init"}
}

func (gitVCS) PullArgs() []string {
return []string{"pull", "--rebase"}
}

func (gitVCS) VersionArgs() []string {
return []string{"version"}
}

func (gitVCS) VersionRegexp() *regexp.Regexp {
return gitVersionRegexp
}
2 changes: 1 addition & 1 deletion cmd/helps.gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ var helps = map[string]help{
"\n" +
"\"-T\", \"--template\"\n" +
"\n" +
"Set the \"template\" attribute on added files and symlinks. In addition, \"if\n" +
"Set the \"template\" attribute on added files and symlinks. In addition, if\n" +
"the \"--template-auto-generate\" flag is set, chezmoi attempts to automatically\n" +
"generate the template by replacing any template data values with the equivalent\n" +
"template data keys. Longer subsitutions occur before shorter ones.\n",
Expand Down
27 changes: 27 additions & 0 deletions cmd/hgvcs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package cmd

import "regexp"

var hgVersionRegexp = regexp.MustCompile(`^Mercurial Distributed SCM \(version (\d+\.\d+(\.\d+)?\))`)

type hgVCS struct{}

func (hgVCS) CloneArgs(repo, dir string) []string {
return []string{"clone", repo, dir}
}

func (hgVCS) InitArgs() []string {
return []string{"init"}
}

func (hgVCS) PullArgs() []string {
return []string{"pull", "--rebase", "--update"}
}

func (hgVCS) VersionArgs() []string {
return []string{"version"}
}

func (hgVCS) VersionRegexp() *regexp.Regexp {
return hgVersionRegexp
}
21 changes: 13 additions & 8 deletions cmd/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func init() {
}

func (c *Config) runInitCmd(fs vfs.FS, args []string) error {
vcsInfo, err := c.getVCSInfo()
vcs, err := c.getVCS()
if err != nil {
return err
}
Expand All @@ -48,6 +48,11 @@ func (c *Config) runInitCmd(fs vfs.FS, args []string) error {
return err
}

rawSourceDir, err := fs.RawPath(c.SourceDir)
if err != nil {
return err
}

switch len(args) {
case 0: // init
var initArgs []string
Expand All @@ -61,27 +66,27 @@ func (c *Config) runInitCmd(fs vfs.FS, args []string) error {
return fmt.Errorf("sourceVCS.init: cannot parse value")
}
} else {
initArgs = vcsInfo.initArgs
initArgs = vcs.InitArgs()
}
if err := c.run(c.SourceDir, c.SourceVCS.Command, initArgs...); err != nil {
if err := c.run(fs, c.SourceDir, c.SourceVCS.Command, initArgs...); err != nil {
return err
}
case 1: // clone
if vcsInfo.cloneArgsFunc == nil {
cloneArgs := vcs.CloneArgs(args[0], rawSourceDir)
if cloneArgs == nil {
return fmt.Errorf("%s: cloning not supported", c.SourceVCS.Command)
}
cloneArgs := vcsInfo.cloneArgsFunc(args[0], c.SourceDir)
if err := c.run("", c.SourceVCS.Command, cloneArgs...); err != nil {
if err := c.run(fs, "", c.SourceVCS.Command, cloneArgs...); err != nil {
return err
}
// FIXME this should be part of struct vcs
// FIXME this should be part of VCS
if filepath.Base(c.SourceVCS.Command) == "git" {
if _, err := fs.Stat(filepath.Join(c.SourceDir, ".gitmodules")); err == nil {
for _, args := range [][]string{
{"submodule", "init"},
{"submodule", "update"},
} {
if err := c.run(c.SourceDir, c.SourceVCS.Command, args...); err != nil {
if err := c.run(fs, c.SourceDir, c.SourceVCS.Command, args...); err != nil {
return err
}
}
Expand Down
70 changes: 70 additions & 0 deletions cmd/init_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package cmd

import (
"bytes"
"os"
"path/filepath"
"runtime"
"strings"
"testing"
Expand Down Expand Up @@ -54,3 +56,71 @@ func TestCreateConfigFile(t *testing.T) {
"os": runtime.GOOS,
}, conf.Data)
}

func TestInit(t *testing.T) {
fs, cleanup, err := vfst.NewTestFS(map[string]interface{}{
"/home/user": &vfst.Dir{Perm: 0755},
})
require.NoError(t, err)
defer cleanup()

c := &Config{
SourceDir: "/home/user/.local/share/chezmoi",
SourceVCS: sourceVCSConfig{
Command: "git",
},
bds: xdg.NewTestBaseDirectorySpecification("/home/user", func(string) string { return "" }),
}

require.NoError(t, c.runInitCmd(fs, nil))
vfst.RunTests(t, fs, "",
vfst.TestPath("/home/user/.local/share/chezmoi",
vfst.TestIsDir,
),
vfst.TestPath("/home/user/.local/share/chezmoi/.git",
vfst.TestIsDir,
),
vfst.TestPath("/home/user/.local/share/chezmoi/.git/HEAD",
vfst.TestModeIsRegular,
),
)
}

func TestInitRepo(t *testing.T) {
fs, cleanup, err := vfst.NewTestFS(map[string]interface{}{
"/home/user": &vfst.Dir{Perm: 0755},
})
require.NoError(t, err)
defer cleanup()

c := &Config{
SourceDir: "/home/user/.local/share/chezmoi",
SourceVCS: sourceVCSConfig{
Command: "git",
},
bds: xdg.NewTestBaseDirectorySpecification("/home/user", func(string) string { return "" }),
}

wd, err := os.Getwd()
require.NoError(t, err)
require.NoError(t, c.runInitCmd(fs, []string{filepath.Join(wd, "testdata/gitrepo")}))
vfst.RunTests(t, fs, "",
vfst.TestPath("/home/user/.local/share/chezmoi",
vfst.TestIsDir,
),
vfst.TestPath("/home/user/.local/share/chezmoi/.git",
vfst.TestIsDir,
),
vfst.TestPath("/home/user/.local/share/chezmoi/.git/HEAD",
vfst.TestModeIsRegular,
),
vfst.TestPath("/home/user/.local/share/chezmoi/dot_bashrc",
vfst.TestModeIsRegular,
vfst.TestContentsString("# contents of .bashrc\n"),
),
vfst.TestPath("/home/user/.config/chezmoi/chezmoi.toml",
vfst.TestModeIsRegular,
vfst.TestContentsString("# contents of chezmoi.toml\n"),
),
)
}
6 changes: 3 additions & 3 deletions cmd/merge.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,15 @@ func (c *Config) runMergeCmd(fs vfs.FS, args []string) error {
defer os.RemoveAll(tempDir)

for i, entry := range entries {
if err := c.runMergeCommand(args[i], entry, tempDir); err != nil {
if err := c.runMergeCommand(fs, args[i], entry, tempDir); err != nil {
return err
}
}

return nil
}

func (c *Config) runMergeCommand(arg string, entry chezmoi.Entry, tempDir string) error {
func (c *Config) runMergeCommand(fs vfs.FS, arg string, entry chezmoi.Entry, tempDir string) error {
file, ok := entry.(*chezmoi.File)
if !ok {
return fmt.Errorf("%s: not a file", arg)
Expand Down Expand Up @@ -87,7 +87,7 @@ func (c *Config) runMergeCommand(arg string, entry chezmoi.Entry, tempDir string
args = append(args, targetStatePath)
}

if err := c.run("", c.Merge.Command, args...); err != nil {
if err := c.run(fs, "", c.Merge.Command, args...); err != nil {
return fmt.Errorf("%s: %v", arg, err)
}

Expand Down
2 changes: 1 addition & 1 deletion cmd/secretbitwarden.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func init() {
}

func (c *Config) runBitwardenCmd(fs vfs.FS, args []string) error {
return c.exec(append([]string{c.Bitwarden.Command}, args...))
return c.exec(fs, append([]string{c.Bitwarden.Command}, args...))
}

func (c *Config) bitwardenFunc(args ...string) interface{} {
Expand Down
Loading

0 comments on commit 283d98e

Please sign in to comment.