Skip to content

Commit 5db7efa

Browse files
authored
Ability to optionally ignore generated files (#8)
This gives a user the ability to optionally ignore files generated by the `go generate` command. Fixes #7
1 parent c1cbdcb commit 5db7efa

File tree

5 files changed

+116
-13
lines changed

5 files changed

+116
-13
lines changed

README.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,18 @@ Note that impi does not support regenerating the files, only warns of infraction
2929
## Usage
3030
```
3131
go get -u github.com/pavius/impi/cmd/impi
32-
impi [--local <local import prefix>] --scheme <scheme> <packages>
32+
impi [--local <local import prefix>] [--ignore-generated=<bool>] --scheme <scheme> <packages>
3333
```
3434

3535
[nuclio](https://github.com/nuclio/nuclio) uses impi as follows:
3636
```
3737
impi --local github.com/nuclio/nuclio/ --scheme stdLocalThirdParty ./cmd/... ./pkg/...
3838
```
3939

40+
## Ignoring Generated Files
41+
42+
Set `--ignore-generated=true` to ignore files that have been generated by `go generate`.
43+
4044
## Supported schemes
4145

4246
impi currently supports the following schemes:

cmd/impi/main.go

+9-7
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ type consoleErrorReporter struct{}
1515
type stringArrayFlags []string
1616

1717
func (saf *stringArrayFlags) String() string {
18-
return strings.Join(*saf, ",")
18+
return strings.Join(*saf, ",")
1919
}
2020

2121
func (saf *stringArrayFlags) Set(value string) error {
22-
*saf = append(*saf, value)
23-
return nil
22+
*saf = append(*saf, value)
23+
return nil
2424
}
2525

2626
func (cer *consoleErrorReporter) Report(err impi.VerificationError) {
@@ -42,6 +42,7 @@ func run() error {
4242

4343
var localPrefix = flag.String("local", "", "prefix of the local repository")
4444
var scheme = flag.String("scheme", "", "verification scheme to enforce. one of stdLocalThirdParty/stdThirdPartyLocal")
45+
var ignoreGenerated = flag.Bool("ignore-generated", false, "ignore files generated by 'go generate'")
4546

4647
var skipPaths stringArrayFlags
4748
flag.Var(&skipPaths, "skip", "paths to skip (regex)")
@@ -67,10 +68,11 @@ func run() error {
6768
}
6869

6970
err = impiInstance.Verify(rootPath, &impi.VerifyOptions{
70-
SkipTests: false,
71-
LocalPrefix: *localPrefix,
72-
Scheme: verificationScheme,
73-
SkipPaths: skipPaths,
71+
SkipTests: false,
72+
LocalPrefix: *localPrefix,
73+
Scheme: verificationScheme,
74+
SkipPaths: skipPaths,
75+
IgnoreGenerated: *ignoreGenerated,
7476
}, &consoleErrorReporter{})
7577

7678
if err != nil {

impi.go

+6-5
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ import (
55
"io/ioutil"
66
"os"
77
"path"
8+
"regexp"
89
"strings"
910

1011
"github.com/kisielk/gotool"
11-
"regexp"
1212
)
1313

1414
// Impi is a single instance that can perform verification on a path
@@ -49,10 +49,11 @@ const (
4949

5050
// VerifyOptions specifies how to perform verification
5151
type VerifyOptions struct {
52-
SkipTests bool
53-
Scheme ImportGroupVerificationScheme
54-
LocalPrefix string
55-
SkipPaths []string
52+
SkipTests bool
53+
Scheme ImportGroupVerificationScheme
54+
LocalPrefix string
55+
SkipPaths []string
56+
IgnoreGenerated bool
5657
}
5758

5859
// VerificationError holds an error and a file path on which the error occurred

verifier.go

+22
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,16 @@ import (
77
"go/parser"
88
"go/token"
99
"io"
10+
"io/ioutil"
1011
"reflect"
12+
"regexp"
1113
"sort"
1214
"strings"
1315
)
1416

17+
// This regex is to appear in generated code.
18+
var generatedRegex = regexp.MustCompile("// Code generated .* DO NOT EDIT\\.")
19+
1520
type verifier struct {
1621
verifyOptions *VerifyOptions
1722
}
@@ -63,6 +68,23 @@ func newVerifier() (*verifier, error) {
6368
func (v *verifier) verify(sourceFileReader io.ReadSeeker, verifyOptions *VerifyOptions) error {
6469
v.verifyOptions = verifyOptions
6570

71+
if verifyOptions.IgnoreGenerated {
72+
// The line specifying that the code was generated can be found anywhere
73+
// within a file. In practice, it is the first line.
74+
fileContents, err := ioutil.ReadAll(sourceFileReader)
75+
if err != nil {
76+
return err
77+
}
78+
79+
if generatedRegex.Match(fileContents) {
80+
return nil
81+
}
82+
83+
if _, err := sourceFileReader.Seek(0, 0); err != nil {
84+
return err
85+
}
86+
}
87+
6688
// get lines on which imports start and end
6789
importLineNumbers, err := v.getImportPos(sourceFileReader)
6890
if err != nil {

verifier_test.go

+74
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package impi
22

33
import (
44
"strings"
5+
"testing"
56

67
"github.com/stretchr/testify/suite"
78
)
@@ -51,3 +52,76 @@ func (s *VerifierTestSuite) verifyTestCases(verificationTestCases []verification
5152
}
5253
}
5354
}
55+
56+
type IgnoreGeneratedFileTestSuite struct {
57+
VerifierTestSuite
58+
}
59+
60+
func (s *IgnoreGeneratedFileTestSuite) SetupSuite() {
61+
s.options.Scheme = ImportGroupVerificationSchemeStdLocalThirdParty
62+
s.options.LocalPrefix = "github.com/pavius/impi"
63+
s.options.IgnoreGenerated = true
64+
}
65+
66+
func (s *IgnoreGeneratedFileTestSuite) TestValidAllGroups() {
67+
verificationTestCases := []verificationTestCase{
68+
{
69+
name: "invalid order, but ignore generated files",
70+
contents: `// Code generated by foo; DO NOT EDIT.
71+
// github.com/example/foo
72+
73+
package fixtures
74+
75+
import (
76+
"fmt"
77+
"os"
78+
"github.com/example/foo"
79+
"path"
80+
)
81+
`,
82+
},
83+
}
84+
s.verifyTestCases(verificationTestCases)
85+
}
86+
87+
func TestIgnoreGeneratedFileTestSuite(t *testing.T) {
88+
suite.Run(t, new(IgnoreGeneratedFileTestSuite))
89+
}
90+
91+
type NotIgnoreGeneratedFileTestSuite struct {
92+
VerifierTestSuite
93+
}
94+
95+
func (s *NotIgnoreGeneratedFileTestSuite) SetupSuite() {
96+
s.options.Scheme = ImportGroupVerificationSchemeStdLocalThirdParty
97+
s.options.LocalPrefix = "github.com/pavius/impi"
98+
}
99+
100+
func (s *NotIgnoreGeneratedFileTestSuite) TestValidAllGroups() {
101+
102+
verificationTestCases := []verificationTestCase{
103+
{
104+
name: "invalid order, not ignoring generated files",
105+
contents: `// Code generated by foo; DO NOT EDIT.
106+
// github.com/example/foo
107+
108+
package fixtures
109+
110+
import (
111+
"fmt"
112+
"os"
113+
"github.com/example/foo"
114+
"path"
115+
)
116+
`,
117+
expectedErrorStrings: []string{
118+
"Imports of different types are not allowed in the same group",
119+
},
120+
},
121+
}
122+
s.verifyTestCases(verificationTestCases)
123+
}
124+
125+
func TestNotIgnoreGeneratedFileTestSuite(t *testing.T) {
126+
suite.Run(t, new(NotIgnoreGeneratedFileTestSuite))
127+
}

0 commit comments

Comments
 (0)