- Expand .golangci.yml with more linters (bodyclose, errcheck, etc.), settings for govet, revive, gocritic, gosec - Add // nolint:gosec comments for intentional file operations and subprocesses - Change file write permissions from 0644 to 0600 for better security - Refactor loops, error handling, and test parallelism with t.Parallel() - Minor fixes: ignore unused args, use errors.Is, adjust mkdir permissions to 0750
63 lines
1.6 KiB
Go
63 lines
1.6 KiB
Go
package git
|
|
|
|
import (
|
|
"fmt"
|
|
"os/exec"
|
|
"strings"
|
|
|
|
"gmgauthier.com/grokkit/internal/logger"
|
|
)
|
|
|
|
func Run(args []string) (string, error) {
|
|
cmdStr := "git " + strings.Join(args, " ")
|
|
logger.Debug("executing git command", "command", cmdStr, "args", args)
|
|
|
|
// nolint:gosec // intentional subprocess for git operation
|
|
out, err := exec.Command("git", args...).Output()
|
|
if err != nil {
|
|
logger.Error("git command failed",
|
|
"command", cmdStr,
|
|
"error", err)
|
|
return "", fmt.Errorf("git command failed: %w", err)
|
|
}
|
|
|
|
outputLen := len(out)
|
|
logger.Debug("git command completed",
|
|
"command", cmdStr,
|
|
"output_length", outputLen)
|
|
|
|
return string(out), nil
|
|
}
|
|
|
|
func IsRepo() bool {
|
|
logger.Debug("checking if directory is a git repository")
|
|
// nolint:gosec // intentional subprocess for git repository check
|
|
_, err := exec.Command("git", "rev-parse", "--is-inside-work-tree").Output()
|
|
isRepo := err == nil
|
|
logger.Debug("git repository check completed", "is_repo", isRepo)
|
|
return isRepo
|
|
}
|
|
|
|
func LatestTag() (string, error) {
|
|
out, err := Run([]string{"describe", "--tags", "--abbrev=0"})
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return strings.TrimSpace(out), nil
|
|
}
|
|
|
|
// PreviousTag returns the tag immediately before the given one.
|
|
func PreviousTag(current string) (string, error) {
|
|
out, err := Run([]string{"describe", "--tags", "--abbrev=0", current + "^"})
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return strings.TrimSpace(out), nil
|
|
}
|
|
|
|
// LogSince returns formatted commit log since the given ref (exactly matches the todo spec).
|
|
func LogSince(since string) (string, error) {
|
|
args := []string{"log", "--pretty=format:%s%n%b%n---", since + "..HEAD"}
|
|
return Run(args)
|
|
}
|