diff --git a/cmd/hepler.go b/cmd/hepler.go index 1949b00..989c59a 100644 --- a/cmd/hepler.go +++ b/cmd/hepler.go @@ -17,6 +17,11 @@ func check() error { return errors.New("git command not found in your system's PATH. Please install Git and try again") } + // Check if current working directory is inside a Git repository. + if !util.IsGitRepo() { + return errors.New("not a git repository") + } + // Apply configuration values from CLI flags to Viper if diffUnified != 3 { viper.Set("git.diff_unified", diffUnified) diff --git a/util/util.go b/util/util.go index 41eeb2b..26d2f56 100644 --- a/util/util.go +++ b/util/util.go @@ -1,6 +1,7 @@ package util import ( + "bytes" "os/exec" "strings" ) @@ -35,3 +36,16 @@ func ConvertToMap(args []string) Data { } return m } + +// IsGitRepo returns true if the current working directory is inside a Git work tree. +func IsGitRepo() bool { + cmd := exec.Command("git", "rev-parse", "--is-inside-work-tree") + + var out bytes.Buffer + cmd.Stdout = &out + if err := cmd.Run(); err != nil { + return false + } + + return strings.TrimSpace(out.String()) == "true" +} diff --git a/util/util_test.go b/util/util_test.go index 99bbea6..e944a2c 100644 --- a/util/util_test.go +++ b/util/util_test.go @@ -2,6 +2,8 @@ package util import ( "os" + "os/exec" + "path/filepath" "reflect" "testing" ) @@ -82,3 +84,100 @@ func TestConvertToMap(t *testing.T) { }) } } + +func TestIsGitRepo(t *testing.T) { + type fields struct { + setup func(t *testing.T) + want bool + } + + testCases := []struct { + name string + fields fields + }{ + { + name: "inside git repo root", + fields: fields{ + want: true, + setup: func(t *testing.T) { + t.Helper() + + tmpDir := t.TempDir() + + cmd := exec.Command("git", "init") + cmd.Dir = tmpDir + if output, err := cmd.CombinedOutput(); err != nil { + t.Fatalf("failed to init git repo: %v, output: %s", err, string(output)) + } + + if err := os.Chdir(tmpDir); err != nil { + t.Fatalf("failed to chdir to repo root: %v", err) + } + }, + }, + }, + { + name: "inside git repo subdir", + fields: fields{ + want: true, + setup: func(t *testing.T) { + t.Helper() + + tmpDir := t.TempDir() + + cmd := exec.Command("git", "init") + cmd.Dir = tmpDir + if output, err := cmd.CombinedOutput(); err != nil { + t.Fatalf("failed to init git repo: %v, output: %s", err, string(output)) + } + + subDir := filepath.Join(tmpDir, "subdir", "nested") + if err := os.MkdirAll(subDir, 0o755); err != nil { + t.Fatalf("failed to create subdir: %v", err) + } + + if err := os.Chdir(subDir); err != nil { + t.Fatalf("failed to chdir to subdir: %v", err) + } + }, + }, + }, + { + name: "outside git repo", + fields: fields{ + want: false, + setup: func(t *testing.T) { + t.Helper() + + tmpDir := t.TempDir() + + if err := os.Chdir(tmpDir); err != nil { + t.Fatalf("failed to chdir to temp dir: %v", err) + } + }, + }, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + origWD, err := os.Getwd() + if err != nil { + t.Fatalf("failed to get current working directory: %v", err) + } + t.Cleanup(func() { + _ = os.Chdir(origWD) + }) + + if tc.fields.setup != nil { + tc.fields.setup(t) + } + + got := IsGitRepo() + if got != tc.fields.want { + t.Errorf("IsGitRepo() = %v; want %v", got, tc.fields.want) + } + }) + } +}