Populate adapter versions in lint reports

This commit is contained in:
Virgil 2026-04-01 06:28:04 +00:00
parent 20875bc066
commit b8ee543bae
3 changed files with 77 additions and 3 deletions

View file

@ -23,6 +23,8 @@ var (
func TestCLI_Run_JSON(t *testing.T) {
dir := t.TempDir()
buildCLI(t)
t.Setenv("PATH", t.TempDir())
require.NoError(t, os.WriteFile(filepath.Join(dir, "go.mod"), []byte("module example.com/test\n"), 0o644))
require.NoError(t, os.WriteFile(filepath.Join(dir, "input.go"), []byte(`package sample

View file

@ -169,13 +169,14 @@ func (adapter CommandAdapter) Run(ctx context.Context, input RunInput, files []s
return result
}
result.Tool.Version = probeCommandVersion(binary, input.Path)
runContext, cancel := context.WithTimeout(ctx, 5*time.Minute)
defer cancel()
args := adapter.buildArgs(input.Path, files)
stdout, stderr, exitCode, runErr := runCommand(runContext, input.Path, binary, args)
result.Tool.Version = ""
result.Tool.Duration = time.Since(startedAt).Round(time.Millisecond).String()
if errors.Is(runContext.Err(), context.DeadlineExceeded) {
@ -233,6 +234,29 @@ func (adapter CommandAdapter) Run(ctx context.Context, input RunInput, files []s
return result
}
func probeCommandVersion(binary string, workingDir string) string {
for _, args := range [][]string{{"--version"}, {"-version"}, {"version"}} {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
stdout, stderr, exitCode, err := runCommand(ctx, workingDir, binary, args)
cancel()
if err != nil && exitCode != 0 {
continue
}
version := firstNonEmpty(stdout, stderr)
if version == "" {
continue
}
if line := firstVersionLine(version); line != "" {
return line
}
}
return ""
}
func (adapter CommandAdapter) availableBinary() (string, bool) {
for _, binary := range adapter.binaries {
path, err := exec.LookPath(binary)
@ -812,6 +836,16 @@ func firstNonEmpty(values ...string) string {
return ""
}
func firstVersionLine(output string) string {
for line := range strings.SplitSeq(strings.TrimSpace(output), "\n") {
line = strings.TrimSpace(line)
if line != "" {
return line
}
}
return ""
}
func slicesContains(values []string, target string) bool {
for _, value := range values {
if value == target {

View file

@ -26,7 +26,7 @@ func Run() {
}
`), 0o644))
svc := NewService()
svc := &Service{adapters: []Adapter{newCatalogAdapter()}}
report, err := svc.Run(context.Background(), RunInput{
Path: dir,
FailOn: "warning",
@ -76,7 +76,7 @@ func run2() {
runTestCommand(t, dir, "git", "add", "go.mod", "staged.go")
svc := NewService()
svc := &Service{adapters: []Adapter{newCatalogAdapter()}}
report, err := svc.Run(context.Background(), RunInput{
Path: dir,
Hook: true,
@ -118,6 +118,44 @@ func TestServiceRun_JS_PrettierFindings(t *testing.T) {
assert.Equal(t, 1, report.Tools[0].Findings)
}
func TestServiceRun_CapturesToolVersion(t *testing.T) {
dir := t.TempDir()
require.NoError(t, os.WriteFile(filepath.Join(dir, "package.json"), []byte("{\n \"name\": \"example\"\n}\n"), 0o644))
require.NoError(t, os.WriteFile(filepath.Join(dir, "index.js"), []byte("const value = 1;\n"), 0o644))
binDir := t.TempDir()
scriptPath := filepath.Join(binDir, "prettier")
script := `#!/bin/sh
case "$1" in
--version)
echo "prettier 3.2.1"
exit 0
;;
--list-different)
echo "index.js"
exit 1
;;
esac
echo "unexpected args: $*" >&2
exit 0
`
require.NoError(t, os.WriteFile(scriptPath, []byte(script), 0o755))
t.Setenv("PATH", binDir+string(os.PathListSeparator)+os.Getenv("PATH"))
svc := &Service{adapters: []Adapter{
newCommandAdapter("prettier", []string{"prettier"}, []string{"js"}, "style", "", false, true, pathArgs("--list-different"), parsePrettierDiagnostics),
}}
report, err := svc.Run(context.Background(), RunInput{
Path: dir,
FailOn: "warning",
})
require.NoError(t, err)
require.Len(t, report.Tools, 1)
assert.Equal(t, "prettier", report.Tools[0].Name)
assert.Equal(t, "prettier 3.2.1", report.Tools[0].Version)
}
func TestServiceRun_Good_DeduplicatesMergedFindings(t *testing.T) {
dir := t.TempDir()
require.NoError(t, os.WriteFile(filepath.Join(dir, "go.mod"), []byte("module example.com/test\n"), 0o644))