1
15
16
17
18
19
20
21
22
23
24
25
26
27 package config
28
29 import (
30 "flag"
31 "fmt"
32 "log"
33 "os"
34 "path/filepath"
35 "strings"
36
37 "github.com/bazelbuild/bazel-gazelle/internal/module"
38 "github.com/bazelbuild/bazel-gazelle/internal/wspace"
39 "github.com/bazelbuild/bazel-gazelle/rule"
40 )
41
42
43
44
45
46
47
48
49
50
51 type Config struct {
52
53
54
55 WorkDir string
56
57
58
59 RepoRoot string
60
61
62 RepoName string
63
64
65
66 ReadBuildFilesDir string
67
68
69
70 WriteBuildFilesDir string
71
72
73
74
75 ValidBuildFileNames []string
76
77
78
79 ShouldFix bool
80
81
82
83 Strict bool
84
85
86
87 IndexLibraries bool
88
89
90
91
92 KindMap map[string]MappedKind
93
94
95
96
97 Repos []*rule.Rule
98
99
100
101 Langs []string
102
103
104
105
106
107 Exts map[string]interface{}
108
109
110 Bzlmod bool
111
112
113
114
115 ModuleToApparentName func(string) string
116 }
117
118
119 type MappedKind struct {
120 FromKind, KindName, KindLoad string
121 }
122
123 func New() *Config {
124 return &Config{
125 ValidBuildFileNames: DefaultValidBuildFileNames,
126 Exts: make(map[string]interface{}),
127 }
128 }
129
130
131
132
133 func (c *Config) Clone() *Config {
134 cc := *c
135 cc.Exts = make(map[string]interface{})
136 for k, v := range c.Exts {
137 cc.Exts[k] = v
138 }
139 cc.KindMap = make(map[string]MappedKind)
140 for k, v := range c.KindMap {
141 cc.KindMap[k] = v
142 }
143 return &cc
144 }
145
146 var DefaultValidBuildFileNames = []string{"BUILD.bazel", "BUILD"}
147
148
149
150 func (c *Config) IsValidBuildFileName(name string) bool {
151 for _, n := range c.ValidBuildFileNames {
152 if name == n {
153 return true
154 }
155 }
156 return false
157 }
158
159
160 func (c *Config) DefaultBuildFileName() string {
161 return c.ValidBuildFileNames[0]
162 }
163
164
165
166
167 type Configurer interface {
168
169
170
171
172 RegisterFlags(fs *flag.FlagSet, cmd string, c *Config)
173
174
175
176
177 CheckFlags(fs *flag.FlagSet, c *Config) error
178
179
180
181
182 KnownDirectives() []string
183
184
185
186
187
188
189
190
191
192
193
194
195 Configure(c *Config, rel string, f *rule.File)
196 }
197
198
199
200 type CommonConfigurer struct {
201 repoRoot, buildFileNames, readBuildFilesDir, writeBuildFilesDir string
202 indexLibraries, strict bool
203 langCsv string
204 bzlmod bool
205 }
206
207 func (cc *CommonConfigurer) RegisterFlags(fs *flag.FlagSet, cmd string, c *Config) {
208 fs.StringVar(&cc.repoRoot, "repo_root", "", "path to a directory which corresponds to go_prefix, otherwise gazelle searches for it.")
209 fs.StringVar(&cc.buildFileNames, "build_file_name", strings.Join(DefaultValidBuildFileNames, ","), "comma-separated list of valid build file names.\nThe first element of the list is the name of output build files to generate.")
210 fs.BoolVar(&cc.indexLibraries, "index", true, "when true, gazelle will build an index of libraries in the workspace for dependency resolution")
211 fs.BoolVar(&cc.strict, "strict", false, "when true, gazelle will exit with none-zero value for build file syntax errors or unknown directives")
212 fs.StringVar(&cc.readBuildFilesDir, "experimental_read_build_files_dir", "", "path to a directory where build files should be read from (instead of -repo_root)")
213 fs.StringVar(&cc.writeBuildFilesDir, "experimental_write_build_files_dir", "", "path to a directory where build files should be written to (instead of -repo_root)")
214 fs.StringVar(&cc.langCsv, "lang", "", "if non-empty, process only these languages (e.g. \"go,proto\")")
215 fs.BoolVar(&cc.bzlmod, "bzlmod", false, "for internal usage only")
216 }
217
218 func (cc *CommonConfigurer) CheckFlags(fs *flag.FlagSet, c *Config) error {
219 var err error
220 if cc.repoRoot == "" {
221 if wsDir := os.Getenv("BUILD_WORKSPACE_DIRECTORY"); wsDir != "" {
222 cc.repoRoot = wsDir
223 } else if parent, err := wspace.FindRepoRoot(c.WorkDir); err == nil {
224 cc.repoRoot = parent
225 } else {
226 return fmt.Errorf("-repo_root not specified, and WORKSPACE cannot be found: %v", err)
227 }
228 }
229 if filepath.IsAbs(cc.repoRoot) {
230 c.RepoRoot = cc.repoRoot
231 } else {
232 c.RepoRoot = filepath.Join(c.WorkDir, cc.repoRoot)
233 }
234 c.RepoRoot, err = filepath.EvalSymlinks(c.RepoRoot)
235 if err != nil {
236 return fmt.Errorf("%s: failed to resolve symlinks: %v", cc.repoRoot, err)
237 }
238 c.ValidBuildFileNames = strings.Split(cc.buildFileNames, ",")
239 if cc.readBuildFilesDir != "" {
240 if filepath.IsAbs(cc.readBuildFilesDir) {
241 c.ReadBuildFilesDir = cc.readBuildFilesDir
242 } else {
243 c.ReadBuildFilesDir = filepath.Join(c.WorkDir, cc.readBuildFilesDir)
244 }
245 }
246 if cc.writeBuildFilesDir != "" {
247 if filepath.IsAbs(cc.writeBuildFilesDir) {
248 c.WriteBuildFilesDir = cc.writeBuildFilesDir
249 } else {
250 c.WriteBuildFilesDir = filepath.Join(c.WorkDir, cc.writeBuildFilesDir)
251 }
252 }
253 c.IndexLibraries = cc.indexLibraries
254 c.Strict = cc.strict
255 if len(cc.langCsv) > 0 {
256 c.Langs = strings.Split(cc.langCsv, ",")
257 }
258 c.Bzlmod = cc.bzlmod
259 c.ModuleToApparentName, err = module.ExtractModuleToApparentNameMapping(c.RepoRoot)
260 if err != nil {
261 return fmt.Errorf("failed to parse MODULE.bazel: %v", err)
262 }
263 return nil
264 }
265
266 func (cc *CommonConfigurer) KnownDirectives() []string {
267 return []string{"build_file_name", "map_kind", "lang"}
268 }
269
270 func (cc *CommonConfigurer) Configure(c *Config, rel string, f *rule.File) {
271 if f == nil {
272 return
273 }
274 for _, d := range f.Directives {
275 switch d.Key {
276 case "build_file_name":
277 c.ValidBuildFileNames = strings.Split(d.Value, ",")
278
279 case "map_kind":
280 vals := strings.Fields(d.Value)
281 if len(vals) != 3 {
282 log.Printf("expected three arguments (gazelle:map_kind from_kind to_kind load_file), got %v", vals)
283 continue
284 }
285 if c.KindMap == nil {
286 c.KindMap = make(map[string]MappedKind)
287 }
288 c.KindMap[vals[0]] = MappedKind{
289 FromKind: vals[0],
290 KindName: vals[1],
291 KindLoad: vals[2],
292 }
293
294 case "lang":
295 if len(d.Value) > 0 {
296 c.Langs = strings.Split(d.Value, ",")
297 } else {
298 c.Langs = nil
299 }
300 }
301 }
302 }
303
View as plain text