1
16
17 package config
18
19 import (
20 "flag"
21 "fmt"
22 "io/ioutil"
23 "os"
24 "path/filepath"
25 "strings"
26 "testing"
27 )
28
29 func ExampleNew() {
30 c := New()
31 fmt.Print(c.String())
32
33
34
35
36 }
37
38 func ExampleExample() {
39 c := Example()
40 fmt.Print(c.String())
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109 }
110
111 func ExampleFlagSet() {
112 c := New()
113 flags := c.FlagSet("buildifier", flag.ExitOnError)
114 flags.VisitAll(func(f *flag.Flag) {
115 fmt.Printf("%s: %s (%q)\n", f.Name, f.Usage, f.DefValue)
116 })
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136 }
137
138 func ExampleFlagSet_parse() {
139 c := New()
140 flags := c.FlagSet("buildifier", flag.ExitOnError)
141 flags.Parse([]string{
142 "--add_tables=/path/to/add_tables.json",
143 "--allowsort=proto_library.deps",
144 "--allowsort=proto_library.srcs",
145 "--buildifier_disable=unsafesort",
146 "--config=/path/to/.buildifier.json",
147 "-d",
148 "--diff_command=diff",
149 "--format=json",
150 "--help",
151 "--lint=fix",
152 "--mode=fix",
153 "--multi_diff=true",
154 "--path=pkg/foo",
155 "-r",
156 "--tables=/path/to/tables.json",
157 "--type=default",
158 "-v",
159 "--version",
160 "--warnings=+print,-no-effect",
161 })
162 fmt.Println("help:", c.Help)
163 fmt.Println("version:", c.Version)
164 fmt.Println("configPath:", c.ConfigPath)
165 fmt.Print(c.String())
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192 }
193
194 func TestValidate(t *testing.T) {
195 for name, tc := range map[string]struct {
196 options string
197 args string
198 wantErr error
199 wantMode string
200 wantLint string
201 wantWarnings []string
202 }{
203 "mode not set": {wantMode: "fix"},
204 "mode check": {options: "--mode=check", wantMode: "check"},
205 "mode diff": {options: "--mode=diff", wantMode: "diff"},
206 "mode d": {options: "-d", wantMode: "diff"},
207 "mode d error": {options: "--mode=diff -d", wantErr: fmt.Errorf("cannot specify both -d and -mode flags")},
208 "mode fix": {options: "--mode=fix", wantMode: "fix"},
209 "mode print_if_changed": {options: "--mode=print_if_changed", wantMode: "print_if_changed"},
210 "mode error": {options: "--mode=foo", wantErr: fmt.Errorf("unrecognized mode foo; valid modes are check, diff, fix, print_if_changed")},
211 "lint not set": {wantLint: "off"},
212 "lint off": {options: "--lint=off", wantLint: "off"},
213 "lint warn": {options: "--lint=warn", wantLint: "warn"},
214 "lint fix": {options: "--lint=fix", wantLint: "fix"},
215 "lint fix error": {options: "--lint=fix --mode=check", wantErr: fmt.Errorf("--lint=fix is only compatible with --mode=fix")},
216 "format mode error": {options: "--mode=fix --format=text", wantErr: fmt.Errorf("cannot specify --format without --mode=check")},
217 "format text": {options: "--mode=check --format=text"},
218 "format json": {options: "--mode=check --format=json"},
219 "format error": {options: "--mode=check --format=foo", wantErr: fmt.Errorf("unrecognized format foo; valid types are text, json")},
220 "type build": {options: "--type=build"},
221 "type bzl": {options: "--type=bzl"},
222 "type workspace": {options: "--type=workspace"},
223 "type default": {options: "--type=default"},
224 "type module": {options: "--type=module"},
225 "type auto": {options: "--type=auto"},
226 "type error": {options: "--type=foo", wantErr: fmt.Errorf("unrecognized input type foo; valid types are build, bzl, workspace, default, module, auto")},
227 "warnings all": {options: "--warnings=all", wantWarnings: []string{
228 "attr-applicable_licenses",
229 "attr-cfg",
230 "attr-license",
231 "attr-licenses",
232 "attr-non-empty",
233 "attr-output-default",
234 "attr-single-file",
235 "build-args-kwargs",
236 "bzl-visibility",
237 "confusing-name",
238 "constant-glob",
239 "ctx-actions",
240 "ctx-args",
241 "deprecated-function",
242 "depset-items",
243 "depset-iteration",
244 "depset-union",
245 "dict-concatenation",
246 "dict-method-named-arg",
247 "duplicated-name",
248 "filetype",
249 "function-docstring",
250 "function-docstring-args",
251 "function-docstring-header",
252 "function-docstring-return",
253 "git-repository",
254 "http-archive",
255 "integer-division",
256 "keyword-positional-params",
257 "list-append",
258 "load",
259 "module-docstring",
260 "name-conventions",
261 "native-android",
262 "native-build",
263 "native-cc",
264 "native-java",
265 "native-package",
266 "native-proto",
267 "native-py",
268 "no-effect",
269 "output-group",
270 "overly-nested-depset",
271 "package-name",
272 "package-on-top",
273 "positional-args",
274 "print",
275 "provider-params",
276 "redefined-variable",
277 "repository-name",
278 "return-value",
279 "rule-impl-return",
280 "skylark-comment",
281 "skylark-docstring",
282 "string-iteration",
283 "uninitialized",
284 "unnamed-macro",
285 "unreachable",
286 "unsorted-dict-items",
287 "unused-variable",
288 }},
289 "warnings default": {options: "--warnings=default", wantWarnings: []string{
290 "attr-applicable_licenses",
291 "attr-cfg",
292 "attr-license",
293 "attr-licenses",
294 "attr-non-empty",
295 "attr-output-default",
296 "attr-single-file",
297 "build-args-kwargs",
298 "bzl-visibility",
299 "confusing-name",
300 "constant-glob",
301 "ctx-actions",
302 "ctx-args",
303 "deprecated-function",
304 "depset-items",
305 "depset-iteration",
306 "depset-union",
307 "dict-concatenation",
308 "dict-method-named-arg",
309 "duplicated-name",
310 "filetype",
311 "function-docstring",
312 "function-docstring-args",
313 "function-docstring-header",
314 "function-docstring-return",
315 "git-repository",
316 "http-archive",
317 "integer-division",
318 "keyword-positional-params",
319 "list-append",
320 "load",
321 "module-docstring",
322 "name-conventions",
323
324 "native-build",
325
326
327 "native-package",
328
329
330 "no-effect",
331 "output-group",
332 "overly-nested-depset",
333 "package-name",
334 "package-on-top",
335 "positional-args",
336 "print",
337 "provider-params",
338 "redefined-variable",
339 "repository-name",
340 "return-value",
341 "rule-impl-return",
342 "skylark-comment",
343 "skylark-docstring",
344 "string-iteration",
345 "uninitialized",
346 "unnamed-macro",
347 "unreachable",
348
349 "unused-variable",
350 }},
351 "warnings plus/minus": {options: "--warnings=+native-cc,-print,-deprecated-function", wantWarnings: []string{
352 "attr-applicable_licenses",
353 "attr-cfg",
354 "attr-license",
355 "attr-licenses",
356 "attr-non-empty",
357 "attr-output-default",
358 "attr-single-file",
359 "build-args-kwargs",
360 "bzl-visibility",
361 "confusing-name",
362 "constant-glob",
363 "ctx-actions",
364 "ctx-args",
365
366 "depset-items",
367 "depset-iteration",
368 "depset-union",
369 "dict-concatenation",
370 "dict-method-named-arg",
371 "duplicated-name",
372 "filetype",
373 "function-docstring",
374 "function-docstring-args",
375 "function-docstring-header",
376 "function-docstring-return",
377 "git-repository",
378 "http-archive",
379 "integer-division",
380 "keyword-positional-params",
381 "list-append",
382 "load",
383 "module-docstring",
384 "name-conventions",
385
386 "native-build",
387
388 "native-package",
389
390
391 "no-effect",
392 "output-group",
393 "overly-nested-depset",
394 "package-name",
395 "package-on-top",
396 "positional-args",
397
398 "provider-params",
399 "redefined-variable",
400 "repository-name",
401 "return-value",
402 "rule-impl-return",
403
404 "skylark-comment",
405 "skylark-docstring",
406 "string-iteration",
407 "uninitialized",
408 "unnamed-macro",
409 "unreachable",
410
411 "unused-variable",
412 "native-cc",
413 }},
414 "warnings error": {options: "--warnings=native-cc,-print,-deprecated-function", wantErr: fmt.Errorf(`warning categories with modifiers ("+" or "-") can't be mixed with raw warning categories`)},
415 } {
416 t.Run(name, func(t *testing.T) {
417 c := New()
418 flags := c.FlagSet("buildifier", flag.ExitOnError)
419 flags.Parse(strings.Fields(tc.options))
420 got := c.Validate(strings.Fields(tc.args))
421 if tc.wantMode != "" && tc.wantMode != c.Mode {
422 t.Fatalf("--mode mismatch: want %v, got %v", tc.wantMode, c.Mode)
423 }
424 if tc.wantLint != "" && tc.wantLint != c.Lint {
425 t.Fatalf("--lint mismatch: want %v, got %v", tc.wantLint, c.Lint)
426 }
427 if len(tc.wantWarnings) > 0 {
428 if len(tc.wantWarnings) != len(c.LintWarnings) {
429 t.Fatalf("--warnings mismatch: want %v, got %v", tc.wantWarnings, c.LintWarnings)
430 }
431 for i, wantWarning := range tc.wantWarnings {
432 gotWarning := c.LintWarnings[i]
433 if wantWarning != gotWarning {
434 t.Errorf("warning mismatch at list position %d: want %s, got %s", i, wantWarning, gotWarning)
435 }
436 }
437 }
438 if tc.wantErr == nil && got == nil {
439 return
440 }
441 if tc.wantErr == nil && got != nil {
442 t.Fatalf("unexpected error: %v", got)
443 }
444 if tc.wantErr != nil && got == nil {
445 t.Fatalf("expected error did not occur: %v", tc.wantErr)
446 }
447 if tc.wantErr.Error() != got.Error() {
448 t.Fatalf("error mismatch: want %v, got %v", tc.wantErr.Error(), got.Error())
449 }
450 })
451 }
452 }
453
454 func TestFindConfigPath(t *testing.T) {
455 for name, tc := range map[string]struct {
456 files map[string]string
457 env map[string]string
458 want string
459 }{
460 "no-config-file": {
461 want: "",
462 },
463 "default": {
464 files: map[string]string{
465 ".buildifier.json": "{}",
466 },
467 want: ".buildifier.json",
468 },
469 "BUILDIFIER_CONFIG-override": {
470 env: map[string]string{
471 "BUILDIFIER_CONFIG": ".buildifier2.json",
472 },
473 want: ".buildifier2.json",
474 },
475 } {
476 t.Run(name, func(t *testing.T) {
477 for k, v := range tc.env {
478 os.Setenv(k, v)
479 defer os.Unsetenv(k)
480 }
481
482 tmp, err := ioutil.TempDir("", name+"*")
483 if err != nil {
484 t.Fatal(err)
485 }
486 defer os.RemoveAll(tmp)
487
488 if err := os.Chdir(tmp); err != nil {
489 t.Fatal(err)
490 }
491
492 t.Log("tmp:", tmp)
493
494 for rel, content := range tc.files {
495 dir := filepath.Join(tmp, filepath.Dir(rel))
496 if dir != "." {
497 if err := os.MkdirAll(dir, os.ModePerm); err != nil {
498 t.Fatal(err)
499 }
500 }
501 filename := filepath.Join(dir, rel)
502 if err := ioutil.WriteFile(filename, []byte(content), 0644); err != nil {
503 t.Fatal(err)
504 }
505 }
506
507 got := FindConfigPath(tmp)
508 got = strings.TrimPrefix(got, tmp)
509 got = strings.TrimPrefix(got, "/")
510
511 if tc.want != got {
512 t.Errorf("FindConfigPath: want %q, got %q", tc.want, got)
513 }
514 })
515 }
516 }
517
View as plain text