Skip to content

Commit

Permalink
feature: Allow providing rc file (#392)
Browse files Browse the repository at this point in the history
Closes #185
  • Loading branch information
mrexox authored Dec 5, 2022
1 parent 93248ee commit 46c7e9b
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 6 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## master (unreleased)

- feature: Allow providing rc file ([PR #392](https://github.com/evilmartians/lefthook/pull/392) by @mrexox)

## 1.2.3 (2022-11-30)

- feature: Expand env variables ([PR #391](https://github.com/evilmartians/lefthook/pull/391) by @mrexox)
Expand Down
60 changes: 60 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- [`skip_output`](#skip_output)
- [`source_dir`](#source_dir)
- [`source_dir_local`](#source_dir_local)
- [`rc`](#rc)
- [`remote` (Beta :test_tube:)](#remote)
- [`git_url`](#git_url)
- [`ref`](#ref)
Expand Down Expand Up @@ -140,6 +141,65 @@ Change a directory for *local* script files (not stored in VCS).

This option is useful if you have a `lefthook-local.yml` config file and want to reference different scripts there.

### `rc`

Provide an [**rc**](https://www.baeldung.com/linux/rc-files) file, which is actually a simple `sh` script. Currently it can be used to set ENV variables that are not accessible from non-shell programs.

**Example**

Use cases:

- You have a GUI program that runs git hooks (e.g., VSCode)
- You reference executables that are accessible only from a tweaked $PATH environment variable (e.g., when using rbenv or nvm)
- Or even if your GUI programm cannot locate the `lefthook` executable :scream:
- Or if you want to use ENV variables that control the executables behavior in `lefthook.yml`

```bash
# An npm executable which is managed by nvm
$ which npm
/home/user/.nvm/versions/node/v15.14.0/bin/npm
```

```yml
# lefthook.yml
pre-commit:
commands:
lint:
run: npm run eslint {staged_files}
```

Provide a tweak to access `npm` executable the same way you do it in your ~/<shell>rc

```yml
# lefthook-local.yml
# You can choose whatever name you want.
# You can share it between projects where you use lefthook.
# Make sure the path is absolute.
rc: ~/.lefthookrc
```

```bash
# ~/.lefthookrc
# An nvm way
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
# Or maybe just
PATH=$PATH:$HOME/.nvm/versions/node/v15.14.0/bin
```

```bash
# Make sure you updated git hooks. This is important.
$ lefthook install -f
```

Now any program that runs your hooks will have a tweaked PATH environment variable and will be able to get `nvm` :wink:

## `remote`

> :test_tube: This feature is in **Beta** version
Expand Down
1 change: 1 addition & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type Config struct {
SkipOutput []string `mapstructure:"skip_output"`
SourceDir string `mapstructure:"source_dir"`
SourceDirLocal string `mapstructure:"source_dir_local"`
Rc string `mapstructure:"rc"`

Hooks map[string]*Hook
}
Expand Down
2 changes: 1 addition & 1 deletion internal/lefthook/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func (l *Lefthook) Add(args *AddArgs) error {
return err
}

err = l.addHook(args.Hook)
err = l.addHook(args.Hook, "")
if err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions internal/lefthook/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,12 +125,12 @@ func (l *Lefthook) createHooksIfNeeded(cfg *config.Config, force bool) error {
return err
}

if err = l.addHook(hook); err != nil {
if err = l.addHook(hook, cfg.Rc); err != nil {
return err
}
}

if err = l.addHook(config.GhostHookName); err != nil {
if err = l.addHook(config.GhostHookName, cfg.Rc); err != nil {
return nil
}

Expand Down
4 changes: 2 additions & 2 deletions internal/lefthook/lefthook.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,9 @@ func (l *Lefthook) cleanHook(hook string, force bool) error {
}

// Creates a hook file using hook template.
func (l *Lefthook) addHook(hook string) error {
func (l *Lefthook) addHook(hook, rc string) error {
hookPath := filepath.Join(l.repo.HooksPath, hook)
return afero.WriteFile(
l.Fs, hookPath, templates.Hook(hook), hookFileMode,
l.Fs, hookPath, templates.Hook(hook, rc), hookFileMode,
)
}
6 changes: 6 additions & 0 deletions internal/templates/hook.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ if [ "$LEFTHOOK" = "0" ]; then
exit 0
fi

{{- if .Rc}}
{{/* Load rc file and export all ENV vars defined in it */}}
set -a
[ -f '{{.Rc}}' ] && source '{{.Rc}}'
{{- end}}

call_lefthook()
{
dir="$(git rev-parse --show-toplevel)"
Expand Down
4 changes: 3 additions & 1 deletion internal/templates/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,16 @@ var templatesFS embed.FS
type hookTmplData struct {
HookName string
Extension string
Rc string
}

func Hook(hookName string) []byte {
func Hook(hookName, rc string) []byte {
buf := &bytes.Buffer{}
t := template.Must(template.ParseFS(templatesFS, "hook.tmpl"))
err := t.Execute(buf, hookTmplData{
HookName: hookName,
Extension: getExtension(),
Rc: rc,
})
if err != nil {
panic(err)
Expand Down

0 comments on commit 46c7e9b

Please sign in to comment.