Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ jobs:
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
- name: Init Hermit
uses: cashapp/activate-hermit@cea9af7913204a965fd488637a8d1811bba2e616 # v1
- name: Install shells
run: sudo apt-get install --no-install-recommends fish zsh
Comment on lines +18 to +19

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure how the maintainers of this repo would feel about this, but i don't see any proper way to test this feature out without this. 😄

- name: Test
run: go test ./...
lint:
Expand Down
8 changes: 4 additions & 4 deletions shell/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ const (
hookEndMarker = "# Generated by Hermit; END; DO NOT EDIT."

fishInstallationScript = `if status is-interactive
set -q HERMIT_ROOT_BIN; or set HERMIT_ROOT_BIN $HOME/bin/hermit
eval "$(test -x $HERMIT_ROOT_BIN && $HERMIT_ROOT_BIN shell-hooks --print --fish)"
set -q HERMIT_ROOT_BIN; or set HERMIT_ROOT_BIN (command -s hermit)
eval "$(test -x "$HERMIT_ROOT_BIN" && "$HERMIT_ROOT_BIN" shell-hooks --print --fish)"
end`
)

Expand All @@ -27,8 +27,8 @@ func installationScript(shell string) string {
return fishInstallationScript
}
return fmt.Sprintf(
`HERMIT_ROOT_BIN="${HERMIT_ROOT_BIN:-"$HOME/bin/hermit"}"`+"\n"+
`eval "$(test -x $HERMIT_ROOT_BIN && $HERMIT_ROOT_BIN shell-hooks --print --%s)"`,
`HERMIT_ROOT_BIN="${HERMIT_ROOT_BIN:-$(command -v hermit)}"`+"\n"+
`eval "$(test -x "$HERMIT_ROOT_BIN" && "$HERMIT_ROOT_BIN" shell-hooks --print --%s)"`,
shell,
)
}
Expand Down
80 changes: 80 additions & 0 deletions shell/hooks_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package shell

import (
"errors"
"os"
"os/exec"
"path/filepath"
"testing"

"github.com/alecthomas/assert/v2"
)

func TestActivationHooksInstallationFindsHermitOnPath(t *testing.T) {
tests := []struct {
name string
sh Shell
args []string
}{
{name: "bash", sh: &Bash{}, args: []string{"-c"}},
{name: "zsh", sh: &Zsh{}, args: []string{"-f", "-c"}},
{name: "fish", sh: &Fish{}, args: []string{"-i", "-c"}},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_, script, err := tt.sh.ActivationHooksInstallation()
assert.NoError(t, err)

shellPath, err := exec.LookPath(tt.name)
if err != nil {
// LookPath returns ErrNotFound both when an executable is absent and
// when PATH cannot resolve it. Optional shells may be skipped locally,
// but CI installs every shell and must fail if one is not discoverable.
if errors.Is(err, exec.ErrNotFound) && tt.name != "bash" && os.Getenv("CI") == "" {
t.Skipf("%s is not installed", tt.name)
}
t.Fatalf("failed to locate %s: %v", tt.name, err)
}

script += `
test "$HERMIT_ROOT_BIN" = "$EXPECTED_HERMIT" && test "$HERMIT_HOOK_LOADED" = 1
`

hermitPath := writeFakeHermit(t)
home := t.TempDir()
cmd := exec.Command(shellPath, append(tt.args, script)...)
cmd.Env = []string{
"EXPECTED_HERMIT=" + hermitPath,
"HOME=" + home,
"PATH=" + filepath.Dir(hermitPath) + string(os.PathListSeparator) + os.Getenv("PATH"),
"XDG_CONFIG_HOME=" + filepath.Join(home, ".config"),
}
output, err := cmd.CombinedOutput()
assert.NoError(t, err, "%s", output)
})
}
}

func writeFakeHermit(t *testing.T) string {
t.Helper()

binDir := filepath.Join(t.TempDir(), "homebrew bin")
err := os.MkdirAll(binDir, 0700)
assert.NoError(t, err)

hermitPath := filepath.Join(binDir, "hermit")
err = os.WriteFile(hermitPath, []byte(`#!/bin/sh
set -eu

test "$1" = shell-hooks
test "$2" = --print
case "$3" in
--bash|--zsh) echo 'export HERMIT_HOOK_LOADED=1' ;;
--fish) echo 'set -gx HERMIT_HOOK_LOADED 1' ;;
*) exit 1 ;;
esac
`), 0700)
assert.NoError(t, err)
return hermitPath
}