From 500c677cc7b8132a54c7e48d816355487cf6cfbc Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Mon, 27 Jan 2025 11:42:47 -0500 Subject: [PATCH] feat: Add git-auto-commit and git-auto-push hooks --- .../reference/configuration-file/hooks.md | 8 ++++--- internal/cmd/config.go | 22 +++++++++++++++++-- internal/cmd/testdata/scripts/autopush.txtar | 17 ++++++++++++++ 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/assets/chezmoi.io/docs/reference/configuration-file/hooks.md b/assets/chezmoi.io/docs/reference/configuration-file/hooks.md index 6fa7ea03cab..5e545dc3ccf 100644 --- a/assets/chezmoi.io/docs/reference/configuration-file/hooks.md +++ b/assets/chezmoi.io/docs/reference/configuration-file/hooks.md @@ -9,15 +9,17 @@ The following events are defined: | Event | Trigger | | --------------------- | --------------------------------------------- | | *command*, e.g. `add` | Running `chezmoi command`, e.g. `chezmoi add` | +| `git-auto-commit` | Generating an automatic git commit | +| `git-auto-push` | Running an automatic git push | | `read-source-state` | Reading the source state | Each event can have a `.pre` and/or a `.post` command. The *event*.`pre` command is executed before *event* occurs and the *event*`.post` command is executed after *event* has occurred. - A command contains a `command` or `script` and an optional array of strings - `args`. `command`s are executed directly. `script`s are executed with -configured interpreter for the script's extension, see the [section on +A command contains a `command` or `script` and an optional array of strings +`args`. `command`s are executed directly. `script`s are executed with configured +interpreter for the script's extension, see the [section on interpreters](interpreters.md). !!! example diff --git a/internal/cmd/config.go b/internal/cmd/config.go index 7b539e31ef5..bcb46dc9edb 100644 --- a/internal/cmd/config.go +++ b/internal/cmd/config.go @@ -1583,7 +1583,16 @@ func (c *Config) gitAutoCommit(cmd *cobra.Command, status *chezmoigit.Status) er if err != nil { return err } - return c.run(c.WorkingTreeAbsPath, c.Git.Command, []string{"commit", "--message", string(commitMessage)}) + if err := c.runHookPre("git-auto-commit"); err != nil { + return err + } + if err := c.run(c.WorkingTreeAbsPath, c.Git.Command, []string{"commit", "--message", string(commitMessage)}); err != nil { + return err + } + if err := c.runHookPost("git-auto-commit"); err != nil { + return err + } + return nil } // gitAutoPush pushes all changes to the remote if status is not empty. @@ -1591,7 +1600,16 @@ func (c *Config) gitAutoPush(status *chezmoigit.Status) error { if status.Empty() { return nil } - return c.run(c.WorkingTreeAbsPath, c.Git.Command, []string{"push"}) + if err := c.runHookPre("git-auto-push"); err != nil { + return err + } + if err := c.run(c.WorkingTreeAbsPath, c.Git.Command, []string{"push"}); err != nil { + return err + } + if err := c.runHookPost("git-auto-push"); err != nil { + return err + } + return nil } // gitCommitMessage returns the git commit message for the given status. diff --git a/internal/cmd/testdata/scripts/autopush.txtar b/internal/cmd/testdata/scripts/autopush.txtar index 6543af0bf4f..0e31afaadab 100644 --- a/internal/cmd/testdata/scripts/autopush.txtar +++ b/internal/cmd/testdata/scripts/autopush.txtar @@ -10,6 +10,10 @@ exec chezmoi init file://$WORK/dotfiles.git # test that chezmoi add creates and pushes a commit exec chezmoi add $HOME${/}.file +stdout ^git-auto-commit-pre$ +stdout ^git-auto-commit-post$ +stdout ^git-auto-push-pre$ +stdout ^git-auto-push-post$ exec git --git-dir=$WORK/dotfiles.git show HEAD stdout 'Add \.file' @@ -41,3 +45,16 @@ stdout 'Remove \.file' -- home/user/.config/chezmoi/chezmoi.toml -- [git] autoPush = true +[hooks.git-auto-commit.pre] + command = "echo" + args = ["git-auto-commit-pre"] +[hooks.git-auto-commit.post] + command = "echo" + args = ["git-auto-commit-post"] +[hooks.git-auto-push.pre] + command = "echo" + args = ["git-auto-push-pre"] +[hooks.git-auto-push.post] + command = "echo" + args = ["git-auto-push-post"] +