@@ -3,13 +3,16 @@ package test
33import (
44 "bufio"
55 "fmt"
6+ "go/build/constraint"
67 "os"
78 "os/exec"
89 "path"
910 "path/filepath"
11+ "runtime"
1012 "strings"
1113 "testing"
1214
15+ hcversion "github.com/hashicorp/go-version"
1316 "github.com/stretchr/testify/require"
1417 "gopkg.in/yaml.v3"
1518
@@ -73,7 +76,10 @@ func TestGoimportsLocal(t *testing.T) {
7376 "--disable-all" , "--print-issued-lines=false" , "--print-linter-name=false" , "--out-format=line-number" ,
7477 sourcePath ,
7578 }
79+
7680 rc := extractRunContextFromComments (t , sourcePath )
81+ require .NotNil (t , rc )
82+
7783 args = append (args , rc .args ... )
7884
7985 cfg , err := yaml .Marshal (rc .config )
@@ -89,7 +95,10 @@ func TestGciLocal(t *testing.T) {
8995 "--disable-all" , "--print-issued-lines=false" , "--print-linter-name=false" , "--out-format=line-number" ,
9096 sourcePath ,
9197 }
98+
9299 rc := extractRunContextFromComments (t , sourcePath )
100+ require .NotNil (t , rc )
101+
93102 args = append (args , rc .args ... )
94103
95104 cfg , err := os .ReadFile (rc .configPath )
@@ -105,7 +114,10 @@ func TestMultipleOutputs(t *testing.T) {
105114 "--disable-all" , "--print-issued-lines=false" , "--print-linter-name=false" , "--out-format=line-number,json:stdout" ,
106115 sourcePath ,
107116 }
117+
108118 rc := extractRunContextFromComments (t , sourcePath )
119+ require .NotNil (t , rc )
120+
109121 args = append (args , rc .args ... )
110122
111123 cfg , err := os .ReadFile (rc .configPath )
@@ -122,7 +134,10 @@ func TestStderrOutput(t *testing.T) {
122134 "--disable-all" , "--print-issued-lines=false" , "--print-linter-name=false" , "--out-format=line-number,json:stderr" ,
123135 sourcePath ,
124136 }
137+
125138 rc := extractRunContextFromComments (t , sourcePath )
139+ require .NotNil (t , rc )
140+
126141 args = append (args , rc .args ... )
127142
128143 cfg , err := os .ReadFile (rc .configPath )
@@ -142,7 +157,10 @@ func TestFileOutput(t *testing.T) {
142157 fmt .Sprintf ("--out-format=json:%s,line-number" , resultPath ),
143158 sourcePath ,
144159 }
160+
145161 rc := extractRunContextFromComments (t , sourcePath )
162+ require .NotNil (t , rc )
163+
146164 args = append (args , rc .args ... )
147165
148166 cfg , err := os .ReadFile (rc .configPath )
@@ -188,8 +206,11 @@ func testOneSource(t *testing.T, sourcePath string) {
188206 }
189207
190208 rc := extractRunContextFromComments (t , sourcePath )
191- var cfgPath string
209+ if rc == nil {
210+ t .Skipf ("Skipped: %s" , sourcePath )
211+ }
192212
213+ var cfgPath string
193214 if rc .config != nil {
194215 p , finish := saveConfig (t , rc .config )
195216 defer finish ()
@@ -254,6 +275,7 @@ func skipMultilineComment(scanner *bufio.Scanner) {
254275 }
255276}
256277
278+ //nolint:gocyclo,funlen
257279func extractRunContextFromComments (t * testing.T , sourcePath string ) * runContext {
258280 f , err := os .Open (sourcePath )
259281 require .NoError (t , err )
@@ -275,6 +297,17 @@ func extractRunContextFromComments(t *testing.T, sourcePath string) *runContext
275297 break
276298 }
277299
300+ if strings .HasPrefix (line , "//go:build" ) || strings .HasPrefix (line , "// +build" ) {
301+ parse , err := constraint .Parse (line )
302+ require .NoError (t , err )
303+
304+ if ! parse .Eval (buildTagGoVersion ) {
305+ return nil
306+ }
307+
308+ continue
309+ }
310+
278311 line = strings .TrimLeft (strings .TrimPrefix (line , "//" ), " " )
279312 if strings .HasPrefix (line , "args: " ) {
280313 require .Nil (t , rc .args )
@@ -315,10 +348,7 @@ func extractRunContextFromComments(t *testing.T, sourcePath string) *runContext
315348 if rc .expectedLinter == "" {
316349 for _ , arg := range rc .args {
317350 if strings .HasPrefix (arg , "-E" ) && ! strings .Contains (arg , "," ) {
318- if rc .expectedLinter != "" {
319- require .Fail (t , "could not infer expected linter for errors because multiple linters are enabled. Please use the `expected_linter: ` directive in your test to indicate the linter-under-test." ) //nolint:lll
320- break
321- }
351+ require .Empty (t , rc .expectedLinter , "could not infer expected linter for errors because multiple linters are enabled. Please use the `expected_linter: ` directive in your test to indicate the linter-under-test." ) //nolint:lll
322352 rc .expectedLinter = arg [2 :]
323353 }
324354 }
@@ -327,19 +357,38 @@ func extractRunContextFromComments(t *testing.T, sourcePath string) *runContext
327357 return rc
328358}
329359
360+ func buildTagGoVersion (tag string ) bool {
361+ vRuntime , err := hcversion .NewVersion (strings .TrimPrefix (runtime .Version (), "go" ))
362+ if err != nil {
363+ return false
364+ }
365+
366+ vTag , err := hcversion .NewVersion (strings .TrimPrefix (tag , "go" ))
367+ if err != nil {
368+ return false
369+ }
370+
371+ return vRuntime .GreaterThanOrEqual (vTag )
372+ }
373+
330374func TestExtractRunContextFromComments (t * testing.T ) {
331375 rc := extractRunContextFromComments (t , filepath .Join (testdataDir , "goimports" , "goimports.go" ))
376+ require .NotNil (t , rc )
332377 require .Equal (t , []string {"-Egoimports" }, rc .args )
333378}
334379
335380func TestTparallel (t * testing.T ) {
336381 t .Run ("should fail on missing top-level Parallel()" , func (t * testing.T ) {
337382 sourcePath := filepath .Join (testdataDir , "tparallel" , "missing_toplevel_test.go" )
338383 args := []string {
339- "--disable-all" , "--print-issued-lines=false" , "--print-linter-name=false" , "--out-format=line-number" , "--enable" , "tparallel" ,
384+ "--disable-all" , "--enable" , "tparallel" ,
385+ "--print-issued-lines=false" , "--print-linter-name=false" , "--out-format=line-number" ,
340386 sourcePath ,
341387 }
388+
342389 rc := extractRunContextFromComments (t , sourcePath )
390+ require .NotNil (t , rc )
391+
343392 args = append (args , rc .args ... )
344393
345394 cfg , err := yaml .Marshal (rc .config )
@@ -354,10 +403,14 @@ func TestTparallel(t *testing.T) {
354403 t .Run ("should fail on missing subtest Parallel()" , func (t * testing.T ) {
355404 sourcePath := filepath .Join (testdataDir , "tparallel" , "missing_subtest_test.go" )
356405 args := []string {
357- "--disable-all" , "--print-issued-lines=false" , "--print-linter-name=false" , "--out-format=line-number" , "--enable" , "tparallel" ,
406+ "--disable-all" , "--enable" , "tparallel" ,
407+ "--print-issued-lines=false" , "--print-linter-name=false" , "--out-format=line-number" ,
358408 sourcePath ,
359409 }
410+
360411 rc := extractRunContextFromComments (t , sourcePath )
412+ require .NotNil (t , rc )
413+
361414 args = append (args , rc .args ... )
362415
363416 cfg , err := yaml .Marshal (rc .config )
@@ -372,10 +425,14 @@ func TestTparallel(t *testing.T) {
372425 t .Run ("should pass on parallel test with no subtests" , func (t * testing.T ) {
373426 sourcePath := filepath .Join (testdataDir , "tparallel" , "happy_path_test.go" )
374427 args := []string {
375- "--disable-all" , "--print-issued-lines=false" , "--print-linter-name=false" , "--out-format=line-number" , "--enable" , "tparallel" ,
428+ "--disable-all" , "--enable" , "tparallel" ,
429+ "--print-issued-lines=false" , "--print-linter-name=false" , "--out-format=line-number" ,
376430 sourcePath ,
377431 }
432+
378433 rc := extractRunContextFromComments (t , sourcePath )
434+ require .NotNil (t , rc )
435+
379436 args = append (args , rc .args ... )
380437
381438 cfg , err := yaml .Marshal (rc .config )
0 commit comments