Skip to content

Commit

Permalink
Merge pull request #363 from twpayne/remove
Browse files Browse the repository at this point in the history
Add initial remove functionality
  • Loading branch information
twpayne committed Jun 22, 2019
2 parents f1372a4 + 64d52b4 commit e529e29
Show file tree
Hide file tree
Showing 14 changed files with 351 additions and 43 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/*coverage.out
/bin
/chezmoi
/dist
/goreleaser/goreleaser.host.yaml
Expand Down
118 changes: 118 additions & 0 deletions cmd/apply_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,124 @@ func TestApplyCommand(t *testing.T) {
}
}

func TestApplyRemove(t *testing.T) {
for _, tc := range []struct {
name string
noRemove bool
root interface{}
data map[string]interface{}
tests []vfst.Test
}{
{
name: "simple",
root: map[string]interface{}{
"/home/user/.local/share/chezmoi/.chezmoiremove": "foo",
"/home/user/foo": "# contents of foo\n",
},
tests: []vfst.Test{
vfst.TestPath("/home/user/foo",
vfst.TestDoesNotExist,
),
},
},
{
name: "no_remove",
noRemove: true,
root: map[string]interface{}{
"/home/user/.local/share/chezmoi/.chezmoiremove": "foo",
"/home/user/foo": "# contents of foo\n",
},
tests: []vfst.Test{
vfst.TestPath("/home/user/foo",
vfst.TestModeIsRegular,
vfst.TestContentsString("# contents of foo\n"),
),
},
},
{
name: "pattern",
root: map[string]interface{}{
"/home/user/.local/share/chezmoi/.chezmoiremove": "f*",
"/home/user/foo": "# contents of foo\n",
},
tests: []vfst.Test{
vfst.TestPath("/home/user/foo",
vfst.TestDoesNotExist,
),
},
},
{
name: "template",
root: map[string]interface{}{
"/home/user/.local/share/chezmoi/.chezmoiremove": "{{ .bar }}",
"/home/user/foo": "# contents of foo\n",
},
data: map[string]interface{}{
"bar": "foo",
},
tests: []vfst.Test{
vfst.TestPath("/home/user/foo",
vfst.TestDoesNotExist,
),
},
},
{
name: "dont_remove_negative_pattern",
root: map[string]interface{}{
"/home/user/.local/share/chezmoi/.chezmoiremove": "f*\n!foo\n",
"/home/user/foo": "# contents of foo\n",
},
tests: []vfst.Test{
vfst.TestPath("/home/user/foo",
vfst.TestModeIsRegular,
vfst.TestContentsString("# contents of foo\n"),
),
},
},
{
name: "dont_remove_ignored",
root: map[string]interface{}{
"/home/user/.local/share/chezmoi/.chezmoiignore": "foo",
"/home/user/.local/share/chezmoi/.chezmoiremove": "f*",
"/home/user/foo": "# contents of foo\n",
},
tests: []vfst.Test{
vfst.TestPath("/home/user/foo",
vfst.TestModeIsRegular,
vfst.TestContentsString("# contents of foo\n"),
),
},
},
{
name: "remove_subdirectory_first",
root: map[string]interface{}{
"/home/user/.local/share/chezmoi/.chezmoiremove": "foo\nfoo/bar\n",
"/home/user/foo/bar": "# contents of bar\n",
},
tests: []vfst.Test{
vfst.TestPath("/home/user/foo",
vfst.TestDoesNotExist,
),
},
},
} {
t.Run(tc.name, func(t *testing.T) {
fs, cleanup, err := vfst.NewTestFS(tc.root)
require.NoError(t, err)
defer cleanup()
c := &Config{
SourceDir: "/home/user/.local/share/chezmoi",
DestDir: "/home/user",
Data: tc.data,
Remove: !tc.noRemove,
Umask: 022,
}
assert.NoError(t, c.runApplyCmd(fs, nil))
vfst.RunTests(t, fs, "", tc.tests)
})
}
}

func TestApplyScript(t *testing.T) {
tempDir, err := ioutil.TempDir("", "chezmoi")
require.NoError(t, err)
Expand Down
7 changes: 5 additions & 2 deletions cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ type Config struct {
DestDir string
Umask permValue
DryRun bool
Remove bool
Verbose bool
Color string
GPG chezmoi.GPG
Expand Down Expand Up @@ -130,6 +131,7 @@ func (c *Config) addTemplateFunc(key string, value interface{}) {
}

func (c *Config) applyArgs(fs vfs.FS, args []string, mutator chezmoi.Mutator) error {
fs = vfs.NewReadOnlyFS(fs)
ts, err := c.getTargetState(fs)
if err != nil {
return err
Expand All @@ -139,6 +141,7 @@ func (c *Config) applyArgs(fs vfs.FS, args []string, mutator chezmoi.Mutator) er
DryRun: c.DryRun,
Ignore: ts.TargetIgnore.Match,
PersistentState: c.persistentState,
Remove: c.Remove,
ScriptStateBucket: c.scriptStateBucket,
Stdout: c.Stdout(),
Umask: ts.Umask,
Expand Down Expand Up @@ -250,6 +253,7 @@ func (c *Config) getEntries(fs vfs.Stater, ts *chezmoi.TargetState, args []strin
}

func (c *Config) getTargetState(fs vfs.FS) (*chezmoi.TargetState, error) {
fs = vfs.NewReadOnlyFS(fs)
defaultData, err := getDefaultData(fs)
if err != nil {
return nil, err
Expand All @@ -265,8 +269,7 @@ func (c *Config) getTargetState(fs vfs.FS) (*chezmoi.TargetState, error) {
c.GPG.Recipient = c.GPGRecipient
}
ts := chezmoi.NewTargetState(c.DestDir, os.FileMode(c.Umask), c.SourceDir, data, c.templateFuncs, &c.GPG)
readOnlyFS := vfs.NewReadOnlyFS(fs)
if err := ts.Populate(readOnlyFS); err != nil {
if err := ts.Populate(fs); err != nil {
return nil, err
}
if Version != nil && ts.MinVersion != nil && Version.LessThan(*ts.MinVersion) {
Expand Down
3 changes: 3 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ func init() {
persistentFlags.BoolVarP(&config.DryRun, "dry-run", "n", false, "dry run")
_ = viper.BindPFlag("dry-run", persistentFlags.Lookup("dry-run"))

persistentFlags.BoolVar(&config.Remove, "remove", false, "remove targets")
_ = viper.BindPFlag("remove", persistentFlags.Lookup("remove"))

persistentFlags.StringVarP(&config.SourceDir, "source", "S", getDefaultSourceDir(config.bds), "source directory")
_ = viper.BindPFlag("source", persistentFlags.Lookup("source"))

Expand Down
Loading

0 comments on commit e529e29

Please sign in to comment.