11 // processGolistOverlay provides rudimentary support for adding
12 // files that don't exist on disk to an overlay. The results can be
13 // sometimes incorrect.
14 // TODO(matloob): Handle unsupported cases, including the following:
16 // - adding test and non-test files to test variants of packages
17 // - determining the correct package to add given a new import path
18 // - creating packages that don't exist
19 func processGolistOverlay(cfg *Config, response *driverResponse) (modifiedPkgs, needPkgs []string, err error) {
20 havePkgs := make(map[string]string) // importPath -> non-test package ID
21 needPkgsSet := make(map[string]bool)
22 modifiedPkgsSet := make(map[string]bool)
24 for _, pkg := range response.Packages {
25 // This is an approximation of import path to id. This can be
26 // wrong for tests, vendored packages, and a number of other cases.
27 havePkgs[pkg.PkgPath] = pkg.ID
31 for path, contents := range cfg.Overlay {
32 base := filepath.Base(path)
33 if strings.HasSuffix(path, "_test.go") {
34 // Overlays don't support adding new test files yet.
35 // TODO(matloob): support adding new test files.
38 dir := filepath.Dir(path)
39 for _, pkg := range response.Packages {
40 var dirContains, fileExists bool
41 for _, f := range pkg.GoFiles {
42 if sameFile(filepath.Dir(f), dir) {
45 if filepath.Base(f) == base {
51 pkg.GoFiles = append(pkg.GoFiles, path) // TODO(matloob): should the file just be added to GoFiles?
52 pkg.CompiledGoFiles = append(pkg.CompiledGoFiles, path)
53 modifiedPkgsSet[pkg.ID] = true
55 imports, err := extractImports(path, contents)
57 // Let the parser or type checker report errors later.
60 for _, imp := range imports {
61 _, found := pkg.Imports[imp]
63 needPkgsSet[imp] = true
64 // TODO(matloob): Handle cases when the following block isn't correct.
65 // These include imports of test variants, imports of vendored packages, etc.
66 id, ok := havePkgs[imp]
70 pkg.Imports[imp] = &Package{ID: id}
78 needPkgs = make([]string, 0, len(needPkgsSet))
79 for pkg := range needPkgsSet {
80 needPkgs = append(needPkgs, pkg)
82 modifiedPkgs = make([]string, 0, len(modifiedPkgsSet))
83 for pkg := range modifiedPkgsSet {
84 modifiedPkgs = append(modifiedPkgs, pkg)
86 return modifiedPkgs, needPkgs, err
89 func extractImports(filename string, contents []byte) ([]string, error) {
90 f, err := parser.ParseFile(token.NewFileSet(), filename, contents, parser.ImportsOnly) // TODO(matloob): reuse fileset?
95 for _, imp := range f.Imports {
96 quotedPath := imp.Path.Value
97 path, err := strconv.Unquote(quotedPath)
101 res = append(res, path)