Skip to content

Commit b24d6f8

Browse files
committed
Make the parser ignore all previously generated Go files
to avoid the chicken-egg problem (ie. syntax errors in file we're currently generating)
1 parent 007aa08 commit b24d6f8

File tree

1 file changed

+24
-14
lines changed

1 file changed

+24
-14
lines changed

parser.go

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,28 +24,38 @@ type Target struct {
2424

2525
// Parse Go source file or package folder and return WebRPC schema.
2626
func Parse(filePath string) ([]*Target, error) {
27-
path, err := filepath.Abs(filePath)
27+
dir, err := filepath.Abs(filePath)
2828
if err != nil {
29-
return nil, fmt.Errorf("failed to get directory from %q: %w", path, err)
29+
return nil, fmt.Errorf("failed to get directory from %q: %w", dir, err)
3030
}
3131

32-
file, err := os.Stat(path)
33-
if err != nil {
34-
return nil, fmt.Errorf("failed to open %q", path)
35-
}
36-
if file.Mode().IsRegular() {
37-
// Parse all files in the given schema file's directory, so the parser can see all the pkg files.
38-
path = filepath.Dir(path)
32+
// Parse the whole directory even if a single file is provided,
33+
// so the parser can see all pkg files.
34+
if file, err := os.Stat(dir); err != nil {
35+
return nil, fmt.Errorf("failed to open %q", dir)
36+
} else if file.Mode().IsRegular() {
37+
dir = filepath.Dir(dir)
3938
}
4039

4140
cfg := &packages.Config{
42-
Dir: path,
43-
Mode: packages.NeedName | packages.NeedSyntax | packages.NeedTypes | packages.NeedTypesInfo | packages.NeedImports,
41+
Dir: dir,
42+
Mode: packages.NeedName | packages.NeedSyntax | packages.NeedTypes | packages.NeedTypesInfo | packages.NeedImports,
43+
Overlay: map[string][]byte{},
4444
}
4545

46-
pkgs, err := packages.Load(cfg, path)
46+
// Make the parser ignore all previously generated Go files to avoid the
47+
// chicken-egg problem (ie. syntax errors in file we're currently generating).
48+
_ = filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
49+
if err == nil && !info.IsDir() && strings.HasSuffix(path, ".gen.go") {
50+
// Overlay the source with an empty package name.
51+
cfg.Overlay[path] = []byte(fmt.Sprintf("package %s", filepath.Base(dir)))
52+
}
53+
return nil
54+
})
55+
56+
pkgs, err := packages.Load(cfg, dir)
4757
if err != nil {
48-
return nil, fmt.Errorf("failed to load Go packages from %q: %w", path, err)
58+
return nil, fmt.Errorf("failed to load Go packages from %q: %w", dir, err)
4959
}
5060

5161
// Print all errors.
@@ -60,7 +70,7 @@ func Parse(filePath string) ([]*Target, error) {
6070
}
6171

6272
if len(pkgs) != 1 {
63-
return nil, fmt.Errorf("failed to load Go package (len=%v) from %q", len(pkgs), path)
73+
return nil, fmt.Errorf("failed to load Go package (len=%v) from %q", len(pkgs), dir)
6474
}
6575
pkg := pkgs[0]
6676

0 commit comments

Comments
 (0)