Skip to content

Commit

Permalink
Append path arguments to diff command if not provided by user
Browse files Browse the repository at this point in the history
  • Loading branch information
twpayne committed Sep 8, 2021
1 parent 4fa36ee commit 57ab1f2
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 13 deletions.
5 changes: 3 additions & 2 deletions docs/REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -1026,8 +1026,9 @@ If `diff.command` is set then it will be invoked to show individual file
differences with `diff.args` passed as arguments. Each element of `diff.args` is
interpreted as a template with the variables `.Destination` and `.Target`
available corresponding to the path of the file in the source and target state
respectively. The default value of `diff.args` is `["{{ .Destination }}",
"{{ .Target }}"]`.
respectively. The default value of `diff.args` is `["{{ .Destination }}", "{{
.Target }}"]`. If `diff.args` does not contain any template arguments then `{{
.Destination }}` and `{{ .Target }}` will be appended automatically.

#### `--pager` *pager*

Expand Down
24 changes: 24 additions & 0 deletions internal/chezmoi/externaldiffsystem.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,17 +178,41 @@ func (s *ExternalDiffSystem) runDiffCommand(destAbsPath, targetAbsPath AbsPath)
Destination: string(destAbsPath),
Target: string(targetAbsPath),
}

args := make([]string, 0, len(s.args))
// Work around a regression introduced in 2.1.5
// (https://github.com/twpayne/chezmoi/pull/1328) in a user-friendly way.
//
// Prior to #1328, the diff.args config option was prepended to the default
// order of files to the diff command. Post #1328, the diff.args config
// option replaced all arguments to the diff command.
//
// Work around this by looking for any templates in diff.args. An arg is
// considered a template if, after execution as as template, it is not equal
// to the original arg.
anyTemplateArgs := false
for i, arg := range s.args {
tmpl, err := template.New("diff.args[" + strconv.Itoa(i) + "]").Parse(arg)
if err != nil {
return err
}

var sb strings.Builder
if err := tmpl.Execute(&sb, templateData); err != nil {
return err
}
args = append(args, sb.String())

// Detect template arguments.
if arg != sb.String() {
anyTemplateArgs = true
}
}

// If there are no template arguments, then append the destination and
// target paths as prior to #1328.
if !anyTemplateArgs {
args = append(args, templateData.Destination, templateData.Target)
}

//nolint:gosec
Expand Down
4 changes: 0 additions & 4 deletions internal/cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -265,10 +265,6 @@ func newConfig(options ...configOption) (*Config, error) {
recursive: true,
},
Diff: diffCmdConfig{
Args: []string{
"{{ .Destination }}",
"{{ .Target }}",
},
Exclude: chezmoi.NewEntryTypeSet(chezmoi.EntryTypesNone),
include: chezmoi.NewEntryTypeSet(chezmoi.EntryTypesAll),
},
Expand Down
19 changes: 12 additions & 7 deletions internal/cmd/testdata/scripts/diff_unix.txt
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
[windows] skip 'UNIX only'

chmod 755 bin/vimdiff

# test that chezmoi diff invokes diff.command when configured
chezmoi diff
stdout 'vimdiff .*/home/user/\.file .*/chezmoi-diff.*/\.file' # FIXME should be able to use ${HOME@R} in this regexp
stdout ^${HOME@R}/\.file\s+${WORK@R}/.*/\.file$

# test that chezmoi diff --use-builtin-diff uses the builtin diff even if diff.command is configured
chezmoi diff --use-builtin-diff
cmp stdout golden/diff

-- bin/vimdiff --
#!/bin/sh
# test that chezmoi diff appends the destination and target paths if diff.args does not contain any templates
chhome home2/user
chezmoi diff
stdout ^arg\s+${HOME@R}/\.file\s+${WORK@R}/.*/\.file$

echo vimdiff "$*"
-- golden/diff --
diff --git a/.file b/.file
index bd729e8ee3cc005444c67dc77eed60016886b5e0..b508963510528ab709627ec448026a10a64c72ef 100644
Expand All @@ -24,8 +23,14 @@ index bd729e8ee3cc005444c67dc77eed60016886b5e0..b508963510528ab709627ec448026a10
+# target contents of .file
-- home/user/.config/chezmoi/chezmoi.toml --
[diff]
command = "vimdiff"
command = "echo"
-- home/user/.file --
# destination contents of .file
-- home/user/.local/share/chezmoi/dot_file --
# target contents of .file
-- home2/user/.config/chezmoi/chezmoi.toml --
[diff]
command = "echo"
args = ["arg"]
-- home2/user/.local/share/chezmoi/dot_file --
# source

0 comments on commit 57ab1f2

Please sign in to comment.