1#!/bin/bash
2
3# --- begin runfiles.bash initialization ---
4# Copy-pasted from Bazel's Bash runfiles library (tools/bash/runfiles/runfiles.bash).
5set -euo pipefail
6if [[ ! -d "${RUNFILES_DIR:-/dev/null}" && ! -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then
7  if [[ -f "$0.runfiles_manifest" ]]; then
8    export RUNFILES_MANIFEST_FILE="$0.runfiles_manifest"
9  elif [[ -f "$0.runfiles/MANIFEST" ]]; then
10    export RUNFILES_MANIFEST_FILE="$0.runfiles/MANIFEST"
11  elif [[ -f "$0.runfiles/bazel_tools/tools/bash/runfiles/runfiles.bash" ]]; then
12    export RUNFILES_DIR="$0.runfiles"
13  fi
14fi
15if [[ -f "${RUNFILES_DIR:-/dev/null}/bazel_tools/tools/bash/runfiles/runfiles.bash" ]]; then
16  source "${RUNFILES_DIR}/bazel_tools/tools/bash/runfiles/runfiles.bash"
17elif [[ -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then
18  source "$(grep -m1 "^bazel_tools/tools/bash/runfiles/runfiles.bash " \
19            "$RUNFILES_MANIFEST_FILE" | cut -d ' ' -f 2-)"
20else
21  echo >&2 "ERROR: cannot find @bazel_tools//tools/bash/runfiles:runfiles.bash"
22  exit 1
23fi
24# --- end runfiles.bash initialization ---
25
26die () {
27  echo "$1" 1>&2
28  exit 1
29}
30
31[[ "$1" =~ external/* ]] && buildozer="${{1#external/}}" || buildozer="$TEST_WORKSPACE/$1"
32buildozer="$(rlocation "$buildozer")"
33
34source $TEST_SRCDIR/com_github_bazelbuild_buildtools/buildozer/test_common.sh
35
36## TEST INPUTS
37
38no_deps='go_library(
39    name = "edit",
40)'
41
42empty_deps='go_library(
43    name = "edit",
44    deps = [],
45)'
46
47one_dep='go_library(
48    name = "edit",
49    deps = ["//buildifier:build"],
50)'
51
52two_deps='go_library(
53    name = "edit",
54    deps = [
55        ":local",
56        "//buildifier:build",
57    ],
58)'
59
60two_deps_with_select='go_library(
61    name = "edit",
62    deps = [
63        ":local",
64        "//buildifier:build",
65    ] + select({
66        "//tools/some:condition": [
67            "//some:value",
68            "//some/other:value",
69        ],
70        "//tools/other:condition": [
71            "//yet/another:value",
72        ],
73    }),
74)'
75
76quoted_deps='go_library(
77    name = "edit",
78    deps = [
79        "//buildifier:build",
80        "//foo",
81        "//bar",
82        "\"//baz\"",
83    ],
84)'
85
86## TESTS
87
88function test_add_one_dep() {
89  run "$one_dep" 'add deps //foo' '//pkg:edit'
90  assert_equals 'go_library(
91    name = "edit",
92    deps = [
93        "//buildifier:build",
94        "//foo",
95    ],
96)'
97}
98
99function test_add_dep_no_deps() {
100  run "$no_deps" 'add deps //foo' '//pkg:edit'
101  assert_equals 'go_library(
102    name = "edit",
103    deps = ["//foo"],
104)'
105}
106
107function test_add_dep_quotes() {
108  run "$no_deps" 'add deps "//foo"' '//pkg:edit'
109  assert_equals 'go_library(
110    name = "edit",
111    deps = ["//foo"],
112)'
113}
114
115function test_add_dep_empty_deps() {
116  run "$empty_deps" 'add deps //foo' '//pkg:edit'
117  assert_equals 'go_library(
118    name = "edit",
119    deps = ["//foo"],
120)'
121}
122
123function test_add_dep_two_deps() {
124  run "$two_deps" 'add deps :local2' '//pkg:edit'
125  assert_equals 'go_library(
126    name = "edit",
127    deps = [
128        ":local",
129        ":local2",
130        "//buildifier:build",
131    ],
132)'
133}
134
135function test_add_existing_dep() {
136  in='go_library(
137    name = "edit",
138    deps = [":local"],
139)'
140  ERROR=3 run "$in" 'add deps //pkg:local' '//pkg:edit'
141  assert_equals "$in"
142}
143
144function test_add_existing_dep2() {
145  in='go_library(
146    name = "edit",
147    deps = ["//pkg:local"],
148)'
149  ERROR=3 run "$in" 'add deps //pkg:local' '//pkg:edit'
150  assert_equals "$in"
151}
152
153function test_add_shortened_dep() {
154  in='go_library(
155    name = "edit",
156)'
157  run "$in" 'add deps //pkg:local' '//pkg:edit'
158  assert_equals 'go_library(
159    name = "edit",
160    deps = [":local"],
161)'
162}
163
164function test_sorted_deps() {
165  in='go_library(
166    name = "edit",
167    deps = [
168      ":c",
169      # comment that prevents buildifier reordering
170      ":x",
171      "//foo",
172    ],
173)'
174  run "$in" 'add deps :z :a :e //last' '//pkg:edit'
175  assert_equals 'go_library(
176    name = "edit",
177    deps = [
178        ":a",
179        ":c",
180        ":e",
181        # comment that prevents buildifier reordering
182        ":x",
183        ":z",
184        "//foo",
185        "//last",
186    ],
187)'
188}
189
190function test_add_duplicate_label() {
191  # "build" and ":build" labels are equivalent
192  in='go_library(
193    name = "edit",
194    deps = ["build"],
195)'
196  ERROR=3 run "$in" 'add deps :build' '//pkg:edit'
197  assert_equals 'go_library(
198    name = "edit",
199    deps = ["build"],
200)'
201}
202
203function test_add_duplicate_label2() {
204  # "build" and ":build" labels are equivalent
205  in='go_library(
206    name = "edit",
207    deps = [":build"],
208)'
209  ERROR=3 run "$in" 'add deps build' '//pkg:edit'
210  assert_equals 'go_library(
211    name = "edit",
212    deps = [":build"],
213)'
214}
215
216function test_remove_last_dep() {
217  run "$one_dep" 'remove deps //buildifier:build' '//pkg:edit'
218  assert_equals 'go_library(name = "edit")'
219}
220
221function test_remove_dep() {
222  run "$two_deps" 'remove deps //buildifier:build' '//pkg:edit'
223  assert_equals 'go_library(
224    name = "edit",
225    deps = [":local"],
226)'
227}
228
229function test_remove_dep_outside_of_select() {
230  run "$two_deps_with_select" 'remove deps //buildifier:build' '//pkg:edit'
231  assert_equals 'go_library(
232    name = "edit",
233    deps = [":local"] + select({
234        "//tools/some:condition": [
235            "//some:value",
236            "//some/other:value",
237        ],
238        "//tools/other:condition": [
239            "//yet/another:value",
240        ],
241    }),
242)'
243}
244
245function test_remove_all_deps_outside_of_select() {
246  run "$two_deps_with_select" 'remove deps //buildifier:build :local' '//pkg:edit'
247  assert_equals 'go_library(
248    name = "edit",
249    deps = select({
250        "//tools/some:condition": [
251            "//some:value",
252            "//some/other:value",
253        ],
254        "//tools/other:condition": [
255            "//yet/another:value",
256        ],
257    }),
258)'
259}
260
261function test_remove_dep_in_select() {
262  run "$two_deps_with_select" 'remove deps //some:value' '//pkg:edit'
263  assert_equals 'go_library(
264    name = "edit",
265    deps = [
266        ":local",
267        "//buildifier:build",
268    ] + select({
269        "//tools/some:condition": ["//some/other:value"],
270        "//tools/other:condition": [
271            "//yet/another:value",
272        ],
273    }),
274)'
275}
276
277function test_remove_deps_in_select() {
278  run "$two_deps_with_select" 'remove deps //some:value //some/other:value' '//pkg:edit'
279  assert_equals 'go_library(
280    name = "edit",
281    deps = [
282        ":local",
283        "//buildifier:build",
284    ] + select({
285        "//tools/some:condition": [],
286        "//tools/other:condition": [
287            "//yet/another:value",
288        ],
289    }),
290)'
291}
292
293function test_remove_all_deps_in_select() {
294  run "$two_deps_with_select" 'remove deps //some:value //some/other:value //yet/another:value' '//pkg:edit'
295  assert_equals 'go_library(
296    name = "edit",
297    deps = [
298        ":local",
299        "//buildifier:build",
300    ],
301)'
302}
303
304function test_remove_all_deps() {
305  run "$two_deps_with_select" 'remove deps //some:value //some/other:value //yet/another:value :local //buildifier:build' '//pkg:edit'
306  assert_equals 'go_library(name = "edit")'
307}
308
309function test_remove_dep_quotes() {
310  run "$two_deps" 'remove deps "//buildifier:build"' '//pkg:edit'
311  assert_equals 'go_library(
312    name = "edit",
313    deps = [":local"],
314)'
315}
316
317function test_remove_local_dep() {
318  run "$two_deps" 'remove deps local' '//pkg:edit'
319  assert_equals 'go_library(
320    name = "edit",
321    deps = ["//buildifier:build"],
322)'
323}
324
325function test_remove_two_deps() {
326  run "$two_deps" 'remove deps //buildifier:build :local' '//pkg:edit'
327  assert_equals 'go_library(name = "edit")'
328}
329
330function test_remove_dep_using_long_label() {
331  run "$two_deps" 'remove deps //pkg:local' '//pkg:edit'
332  assert_equals 'go_library(
333    name = "edit",
334    deps = ["//buildifier:build"],
335)'
336}
337
338function test_remove_nonexistent_item() {
339  run "$two_deps" 'remove deps //foo:bar :local' '//pkg:edit'
340  assert_equals 'go_library(
341    name = "edit",
342    deps = ["//buildifier:build"],
343)'
344}
345
346function test_remove_item_with_comment() {
347  commented_deps='go_library(
348    name = "edit",
349    deps = [
350        # Do not remove!!!!11111!!!
351        ":local",
352        "//buildifier:build",  #fixdeps: keep
353        "//remove:me",
354    ],
355)'
356
357  run "$commented_deps" 'remove deps //buildifier:build //remove:me :local' '//pkg:edit'
358  assert_equals 'go_library(name = "edit")'
359}
360
361function test_remove_src() {
362  in='go_library(
363    name = "edit",
364    srcs = ["file" + ".go", "other.go"],
365)'
366  run "$in" 'remove srcs other.go' '//pkg:edit'
367  assert_equals 'go_library(
368    name = "edit",
369    srcs = ["file" + ".go"],
370)'
371}
372
373function test_remove_dep_without_colon() {
374  in='go_library(
375    name = "edit",
376    deps = ["local", "//base"],
377)'
378  run "$in" 'remove deps //pkg:local' '//pkg:edit'
379  assert_equals 'go_library(
380    name = "edit",
381    deps = ["//base"],
382)'
383}
384
385function test_remove_attribute() {
386  run "$two_deps" 'remove deps' '//pkg:edit'
387  assert_equals 'go_library(name = "edit")'
388}
389
390function test_remove_concatenated_attribute() {
391  in='cc_library(name = "a", deps = ["//my/"] + ["foo"])'
392  run "$in" 'remove deps :foo' '//pkg:a'
393  assert_equals 'cc_library(
394    name = "a",
395    deps = ["//my/"],
396)'
397}
398
399function test_remove_from_all_attributes() {
400  in='java_library(name = "a", data = ["b","c"], exports = ["c"], deps = ["c","d"])'
401  run "$in" 'remove * c' '//pkg:a'
402  assert_equals 'java_library(
403    name = "a",
404    data = ["b"],
405    deps = ["d"],
406)'
407}
408
409function test_remove_from_all_rules() {
410  in='cc_library(name = "a", visibility = ["//visibility:private"])
411cc_library(name = "b")
412exports_files(["a.cc"], visibility = ["//visibility:private"])'
413  run "$in" 'remove visibility' '//pkg:all'
414  assert_equals 'cc_library(name = "a")
415
416cc_library(name = "b")
417
418exports_files(["a.cc"])'
419}
420
421function test_remove_package_attribute() {
422  in='package(default_visibility = ["//visibility:public"])'
423  run "$in" 'remove default_visibility' '//pkg:__pkg__'
424  [ $(wc -c < "$root/pkg/BUILD") -eq 0 ] || fail "Expected empty file"
425}
426
427function test_move_last_dep() {
428  run "$one_dep" 'move deps runtime_deps //buildifier:build' '//pkg:edit'
429  assert_equals 'go_library(
430    name = "edit",
431    runtime_deps = ["//buildifier:build"],
432)'
433}
434
435function test_move_dep() {
436  run "$two_deps" 'move deps runtime_deps //buildifier:build' '//pkg:edit'
437  assert_equals 'go_library(
438    name = "edit",
439    runtime_deps = ["//buildifier:build"],
440    deps = [":local"],
441)'
442}
443
444function test_move_two_deps() {
445  run "$two_deps" 'move deps runtime_deps //buildifier:build :local' '//pkg:edit'
446  assert_equals 'go_library(
447    name = "edit",
448    runtime_deps = [
449        ":local",
450        "//buildifier:build",
451    ],
452)'
453}
454
455function test_move_dep_using_long_label() {
456  run "$two_deps" 'move deps runtime_deps //pkg:local' '//pkg:edit'
457  assert_equals 'go_library(
458    name = "edit",
459    runtime_deps = [":local"],
460    deps = ["//buildifier:build"],
461)'
462}
463
464function test_move_dep_with_comment() {
465  local input='go_library(
466    name = "edit",
467    deps = [
468        ":local",  # needed at runtime for some obscure reason
469        "//buildifier:build",
470    ],
471)'
472  run "$input" 'move deps runtime_deps :local' '//pkg:edit'
473  assert_equals 'go_library(
474    name = "edit",
475    runtime_deps = [
476        ":local",  # needed at runtime for some obscure reason
477    ],
478    deps = ["//buildifier:build"],
479)'
480}
481
482function test_move_nonexistent_item() {
483  run "$two_deps" 'move deps runtime_deps //foo:bar :local' '//pkg:edit'
484  assert_equals 'go_library(
485    name = "edit",
486    runtime_deps = [":local"],
487    deps = ["//buildifier:build"],
488)'
489}
490
491function test_move_all_deps_to_new_attribute() {
492  run "$two_deps" 'move deps runtime_deps *' '//pkg:edit'
493  assert_equals 'go_library(
494    name = "edit",
495    runtime_deps = [
496        ":local",
497        "//buildifier:build",
498    ],
499)'
500}
501
502function test_move_all_deps_to_existing_attribute() {
503  local input='go_library(
504    name = "edit",
505    runtime_deps = [":remote"],
506    deps = [
507        ":local",
508        "//buildifier:build",
509    ],
510)'
511  run "$input" 'move deps runtime_deps *' '//pkg:edit'
512  assert_equals 'go_library(
513    name = "edit",
514    runtime_deps = [
515        ":local",
516        ":remote",
517        "//buildifier:build",
518    ],
519)'
520}
521
522function test_rename_attribute() {
523  run "$two_deps" 'rename deps data' '//pkg:edit'
524  assert_equals 'go_library(
525    name = "edit",
526    data = [
527        ":local",
528        "//buildifier:build",
529    ],
530)'
531}
532
533function test_rename_attribute_already_exist() {
534  in='cc_library(
535    name = "edit",
536    srcs = ["b.h"],
537    hdrs = ["a.h"],
538)'
539  ERROR=2 run "$in" 'rename srcs hdrs' '//pkg:edit'
540  assert_equals "$in"
541  assert_err "attribute hdrs already exists in rule edit"
542}
543
544function test_rename_attribute_does_not_exist() {
545  ERROR=2 run "$two_deps" 'rename data resources' '//pkg:edit'
546  assert_equals "$two_deps"
547  assert_err "no attribute data found in rule edit"
548}
549
550function test_with_python_code() {
551  in='# test that Python code is preserved and does not crash
552top_files = [
553    "lgpl.txt",
554    "README",
555]
556
557boom_files = top_files
558
559boom_files.extend(glob(["**/*.hpp"]))
560
561boom_files.remove("src/math/special_functions.hpp")
562
563# comment for foo
564def foo(x):
565    x += [1, 2]
566
567foo(boom_files)'
568
569  run "$in" 'add default_visibility //visibility:public' '//pkg:__pkg__'
570  assert_equals "package(default_visibility = [\"//visibility:public\"])
571
572$in"
573}
574
575function test_replace_string_attr() {
576  in='go_library(
577    name = "edit",
578    shared_library = ":local",  # Suffix comment.
579)'
580  run "$in" 'replace shared_library :local :new' '//pkg:edit'
581  assert_equals 'go_library(
582    name = "edit",
583    shared_library = ":new",  # Suffix comment.
584)'
585}
586
587function test_replace_string_attr_quotes() {
588  in='go_library(
589    name = "edit",
590    shared_library = ":local",  # Suffix comment.
591)'
592  run "$in" 'replace shared_library ":local" ":new"' '//pkg:edit'
593  assert_equals 'go_library(
594    name = "edit",
595    shared_library = ":new",  # Suffix comment.
596)'
597}
598
599function test_replace_string_attr_no_match() {
600  in='go_library(
601    name = "edit",
602    library = ":no_match",  # Suffix comment.
603)'
604  ERROR=3 run "$in" 'replace library :local :new' '//pkg:edit'
605  assert_equals 'go_library(
606    name = "edit",
607    library = ":no_match",  # Suffix comment.
608)'
609}
610
611function test_replace_concatenated_lists() {
612  in='go_library(
613    name = "edit",
614    deps = [":local"] + CONSTANT,
615)'
616  run "$in" 'replace deps :local :new' '//pkg:edit'
617  assert_equals 'go_library(
618    name = "edit",
619    deps = [":new"] + CONSTANT,
620)'
621}
622
623function test_replace_dep() {
624  in='go_library(
625    name = "edit",
626    deps = [
627        # Before-comment.
628        ":local",  # Suffix comment.
629        "//buildifier:build",
630    ] + select({
631        "//tools/some:condition": [
632            "//some:value",
633        ],
634    }),
635)'
636  run "$in" 'replace deps :local :new' '//pkg:edit'
637  assert_equals 'go_library(
638    name = "edit",
639    deps = [
640        # Before-comment.
641        ":new",  # Suffix comment.
642        "//buildifier:build",
643    ] + select({
644        "//tools/some:condition": [
645            "//some:value",
646        ],
647    }),
648)'
649}
650
651function test_replace_dep_select() {
652  # Replace a dep inside a select statement
653  in='go_library(
654    name = "edit",
655    deps = [":dep"] + select({
656        "//tools/some:condition": [
657            "//some/other:value",
658        ],
659        "//tools/other:condition": [
660            "//yet/another:value",
661        ],
662        "//conditions:default": SOME_CONSTANT,
663    }),
664)'
665  run "$in" 'replace deps //some/other:value :new' '//pkg:edit'
666  assert_equals 'go_library(
667    name = "edit",
668    deps = [":dep"] + select({
669        "//tools/some:condition": [
670            ":new",
671        ],
672        "//tools/other:condition": [
673            "//yet/another:value",
674        ],
675        "//conditions:default": SOME_CONSTANT,
676    }),
677)'
678}
679
680function test_replace_dep_using_long_label() {
681  run "$two_deps" 'replace deps //pkg:local //pkg:new' '//pkg:edit'
682  assert_equals 'go_library(
683    name = "edit",
684    deps = [
685        ":new",
686        "//buildifier:build",
687    ],
688)'
689}
690
691function test_replace_in_all_attributes() {
692  in='java_library(name = "a", data = ["b","c"], exports = ["c"], deps = ["c","d"])'
693  run "$in" 'replace * c e' '//pkg:a'
694  assert_equals 'java_library(
695    name = "a",
696    data = [
697        "b",
698        "e",
699    ],
700    exports = ["e"],
701    deps = [
702        "d",
703        "e",
704    ],
705)'
706}
707
708function test_delete_rule_all() {
709  in='cc_library(name = "all")
710cc_library(name = "b")'
711  run "$in" 'delete' '//pkg:all'
712  assert_equals 'cc_library(name = "b")'
713}
714
715function test_delete_rule_star() {
716  in='cc_library(name = "all")
717cc_library(name = "b")'
718  run "$in" 'delete' '//pkg:*'
719  [ $(wc -c < "$root/pkg/BUILD") -eq 0 ] || fail "Expected empty file"
720}
721
722function test_delete_rule() {
723  in='cc_library(name = "a")
724
725cc_library(name = "b")
726
727# Comment to make sure it is preserved
728
729a = 42
730
731cc_library(name = "c")'
732
733  run "$in" 'delete' '//pkg:b'
734  assert_equals 'cc_library(name = "a")
735
736# Comment to make sure it is preserved
737
738a = 42
739
740cc_library(name = "c")'
741}
742
743function test_delete_package() {
744  in='package(default_visibility = ["//visibility:public"])
745
746cc_library(name = "a")'
747
748  run "$in" 'delete' '//pkg:__pkg__'
749  assert_equals 'cc_library(name = "a")'
750}
751
752function test_delete_missing_package() {
753  in='cc_library(name = "a")'
754  ERROR=3 run "$in" 'delete' '//pkg:__pkg__'
755  assert_equals "$in"
756}
757
758function test_delete_target_without_name() {
759  in='load("/path/f", "a")
760
761a(arg1 = "foo")'
762
763  run "$in" 'delete' '//pkg:%a'
764  assert_equals 'load("/path/f", "a")'
765}
766
767function test_delete_using_line_number() {
768  in='load("/path/f", "a")
769
770a(arg1 = "foo")'
771
772    run "$in" 'delete' '//pkg:%3'
773  assert_equals 'load("/path/f", "a")'
774}
775
776function test_copy() {
777  in='proto_library(name = "from", visibility = ["://foo"] + CONST)
778
779cc_binary(name = "to")'
780
781  run "$in" 'copy visibility from' '//pkg:to'
782  assert_equals 'proto_library(
783    name = "from",
784    visibility = ["://foo"] + CONST,
785)
786
787cc_binary(
788    name = "to",
789    visibility = ["://foo"] + CONST,
790)'
791}
792
793function test_copy_overwrite() {
794  in='proto_library(name = "from", testonly = 1)
795
796cc_binary(name = "to", testonly = 2)'
797
798  run "$in" 'copy testonly from' '//pkg:to'
799  assert_equals 'proto_library(
800    name = "from",
801    testonly = 1,
802)
803
804cc_binary(
805    name = "to",
806    testonly = 1,
807)'
808}
809
810function test_copy_no_overwrite() {
811  in='proto_library(name = "from", visibility = ["://foo"] + CONST)
812
813cc_binary(name = "to")'
814
815  run "$in" 'copy_no_overwrite visibility from' '//pkg:to'
816  assert_equals 'proto_library(
817    name = "from",
818    visibility = ["://foo"] + CONST,
819)
820
821cc_binary(
822    name = "to",
823    visibility = ["://foo"] + CONST,
824)'
825}
826
827function test_copy_no_overwrite_no_overwrite() {
828  in='proto_library(name = "from", testonly = 1)
829
830cc_binary(name = "to", testonly = 2)'
831
832  run "$in" 'copy_no_overwrite testonly from' '//pkg:to'
833  assert_equals 'proto_library(
834    name = "from",
835    testonly = 1,
836)
837
838cc_binary(
839    name = "to",
840    testonly = 2,
841)'
842}
843
844function test_copy_no_from_rule() {
845  in='go_binary(name = "to")'
846  ERROR=2 run "$in" 'copy visibility from' '//pkg:to'
847  assert_err "could not find rule 'from'"
848}
849
850function test_copy_no_attribute() {
851  in='go_binary(name = "from")
852
853go_binary(name = "to")'
854  ERROR=2 run "$in" 'copy visibility from' '//pkg:to'
855  assert_err "rule 'from' does not have attribute 'visibility'"
856}
857
858function test_set_kind() {
859  in='cc_library(name = "a")'
860
861  run "$in" 'set kind java_library' '//pkg:a'
862  assert_equals 'java_library(name = "a")'
863}
864
865function test_set_list() {
866  in='cc_library(name = "a")'
867
868  run "$in" 'set copts foo' '//pkg:a'
869  assert_equals 'cc_library(
870    name = "a",
871    copts = ["foo"],
872)'
873}
874
875function test_set_list() {
876  in='cc_library(name = "a")'
877
878  run "$in" 'set copts foo bar baz' '//pkg:a'
879  assert_equals 'cc_library(
880    name = "a",
881    copts = [
882        "foo",
883        "bar",
884        "baz",
885    ],
886)'
887}
888
889function test_set_string() {
890  in='cc_library(name = "a")'
891
892  run "$in" 'set name b' '//pkg:a'
893  assert_equals 'cc_library(name = "b")'
894}
895
896function test_set_int() {
897  in='cc_test(name = "a")'
898
899  run "$in" 'set shard_count 8' '//pkg:a'
900  assert_equals 'cc_test(
901    name = "a",
902    shard_count = 8,
903)'
904}
905
906function test_set_licenses() {
907  in='cc_test(name = "a")'
908
909  run "$in" 'set licenses foo' '//pkg:a'
910  assert_equals 'cc_test(
911    name = "a",
912    licenses = ["foo"],
913)'
914}
915
916function test_set_distribs() {
917  in='cc_test(name = "a")'
918
919  run "$in" 'set distribs foo' '//pkg:a'
920  assert_equals 'cc_test(
921    name = "a",
922    distribs = ["foo"],
923)'
924}
925
926function test_set_if_absent_absent() {
927  in='soy_js(name = "a")'
928
929  run "$in" 'set_if_absent allowv1syntax 1' '//pkg:a'
930  assert_equals 'soy_js(
931    name = "a",
932    allowv1syntax = 1,
933)'
934}
935
936function test_set_if_absent_present() {
937  in='soy_js(
938  name = "a",
939  allowv1syntax = 0
940  )'
941
942  run "$in" 'set_if_absent allowv1syntax 1' '//pkg:a'
943  assert_equals 'soy_js(
944    name = "a",
945    allowv1syntax = 0,
946)'
947}
948
949function assert_output() {
950  echo "$1" > "expected"
951  diff -u "expected" "$log" || fail "Output didn't match"
952}
953
954function test_print_all_functions() {
955  in='package(default_visibility = ["//visibility:public"])
956cc_test(name = "a")
957java_binary(name = "b")
958exports_files(["a.cc"])'
959  ERROR=3 run "$in" 'print kind' '//pkg:all'
960  assert_output 'package
961cc_test
962java_binary
963exports_files'
964}
965
966function test_print_java_libraries() {
967  in='cc_test(name = "a")
968java_library(name = "b")
969java_library(name = "c")'
970  ERROR=3 run "$in" 'print' '//pkg:%java_library'
971  assert_output 'b java_library
972c java_library'
973}
974
975function test_refer_to_rule_by_location() {
976  in='cc_test(name = "a")
977java_library(name = "b")
978java_library(name = "c")'
979  ERROR=3 run "$in" 'print label' '//pkg:%2'
980  assert_output '//pkg:b'
981}
982
983function test_refer_to_rule_by_location_no_such_rule() {
984  in='cc_test(name = "a")
985java_library(name = "b")
986java_library(name = "c")'
987  ERROR=2 run "$in" 'print label' '//pkg:%999'
988  assert_err "rule '%999' not found"
989}
990
991function test_visibility_exported_file() {
992  in='exports_files(["a.txt", "b.txt"])'
993  run "$in" 'set visibility //foo:__pkg__' '//pkg:b.txt'
994  assert_equals 'exports_files(
995    [
996        "a.txt",
997        "b.txt",
998    ],
999    visibility = ["//foo:__pkg__"],
1000)'
1001}
1002
1003function test_print_srcs() {
1004  in='cc_test(name = "a", srcs = ["foo.cc"])
1005java_library(name = "b")
1006java_library(name = "c", srcs = ["foo.java", "bar.java"])'
1007  ERROR=3 run "$in" 'print name kind srcs' '//pkg:*'
1008  assert_output 'a cc_test [foo.cc]
1009b java_library (missing)
1010c java_library [foo.java bar.java]'
1011  assert_err 'rule "//pkg:b" has no attribute "srcs"'
1012}
1013
1014function test_print_empty_list() {
1015  in='package()
1016java_library(name = "b", deps = [])'
1017  ERROR=3 run "$in" 'print deps' '//pkg:b'
1018  assert_output '[]'
1019}
1020
1021function test_print_label() {
1022  in='package()
1023java_library(name = "b")'
1024  ERROR=3 run "$in" 'print label kind' '//pkg:*'
1025  assert_output '//pkg:b java_library'
1026}
1027
1028function test_print_startline() {
1029  in='package()
1030java_library(name = "b")'
1031  ERROR=3 run "$in" 'print startline label' '//pkg:*'
1032  assert_output '2 //pkg:b'
1033}
1034
1035function test_print_endline() {
1036  in='package()
1037java_library(
1038    name = "b"
1039)'
1040  ERROR=3 run "$in" 'print endline label' '//pkg:*'
1041  assert_output '4 //pkg:b'
1042}
1043
1044function test_print_rule() {
1045  in='cc_library(name = "a")
1046
1047# Comment before
1048cc_test(
1049    name = "b",
1050    copts = [
1051        # comment before
1052        "foo",  # comment after
1053    ],
1054)
1055
1056cc_library(name = "c")'
1057  ERROR=3 run "$in" 'print rule' '//pkg:b'
1058  assert_output '# Comment before
1059cc_test(
1060    name = "b",
1061    copts = [
1062        # comment before
1063        "foo",  # comment after
1064    ],
1065)'
1066}
1067
1068function test_print_version() {
1069  in='gendeb(name = "foobar", version = "12345")'
1070  ERROR=3 run "$in" 'print version' '//pkg:*'
1071  assert_output '12345'
1072}
1073
1074function test_new_cc_library() {
1075  in='cc_test(name = "a")
1076
1077# end of file comment'
1078  run "$in" 'new cc_library foo' '//pkg:__pkg__'
1079  assert_equals 'cc_test(name = "a")
1080
1081cc_library(name = "foo")
1082
1083# end of file comment'
1084}
1085
1086function test_new_cc_library_after_other_libraries() {
1087  in='cc_library(name = "l")
1088cc_test(name = "a")'
1089  run "$in" 'new cc_library foo' '//pkg:__pkg__'
1090  assert_equals 'cc_library(name = "l")
1091
1092cc_library(name = "foo")
1093
1094cc_test(name = "a")'
1095}
1096
1097function test_new_cc_library_empty_file() {
1098  in=''
1099  run "$in" 'new cc_library foo' '//pkg:__pkg__'
1100  assert_equals 'cc_library(name = "foo")'
1101}
1102
1103function test_new_java_library() {
1104  in='cc_test(name = "a")'
1105  run "$in" 'new java_library foo' 'pkg/BUILD'
1106  assert_equals 'cc_test(name = "a")
1107
1108java_library(name = "foo")'
1109}
1110
1111function test_new_already_exists() {
1112  in='cc_test(name = "a")'
1113  ERROR=2 run "$in" 'new cc_library a' '//pkg:__pkg__'
1114  assert_err "rule 'a' already exists"
1115}
1116
1117function test_new_before_first() {
1118  in='cc_test(name = "a")'
1119  run "$in" 'new java_library foo before a' 'pkg/BUILD'
1120  assert_equals 'java_library(name = "foo")
1121
1122cc_test(name = "a")'
1123}
1124
1125function test_new_before_last() {
1126  in='cc_test(name = "a")
1127
1128cc_test(name = "b")'
1129  run "$in" 'new java_library foo before b' 'pkg/BUILD'
1130  assert_equals 'cc_test(name = "a")
1131
1132java_library(name = "foo")
1133
1134cc_test(name = "b")'
1135}
1136
1137function test_new_before_nonexistent_rule() {
1138  in='cc_test(name = "a")
1139
1140cc_test(name = "b")'
1141  run "$in" 'new java_library foo before bar' 'pkg/BUILD'
1142  assert_equals 'cc_test(name = "a")
1143
1144cc_test(name = "b")
1145
1146java_library(name = "foo")'
1147}
1148
1149function test_new_before_already_exists() {
1150  in='cc_test(name = "foo")
1151cc_test(name = "new_rule")'
1152  ERROR=2 run "$in" 'new java_library new_rule before foo' 'pkg/BUILD'
1153  assert_err "rule 'new_rule' already exists"
1154}
1155
1156function test_new_after_first() {
1157  in='cc_test(name = "a")'
1158  run "$in" 'new java_library foo after a' 'pkg/BUILD'
1159  assert_equals 'cc_test(name = "a")
1160
1161java_library(name = "foo")'
1162}
1163
1164function test_new_after_last() {
1165  in='cc_test(name = "a")
1166
1167cc_test(name = "b")'
1168  run "$in" 'new java_library foo after b' 'pkg/BUILD'
1169  assert_equals 'cc_test(name = "a")
1170
1171cc_test(name = "b")
1172
1173java_library(name = "foo")'
1174}
1175
1176function test_new_after_by_location() {
1177  in='
1178cc_test(name = "a")
1179
1180cc_test(name = "b")'
1181  run "$in" 'new java_library foo after %2' 'pkg/BUILD'
1182  assert_equals 'cc_test(name = "a")
1183
1184java_library(name = "foo")
1185
1186cc_test(name = "b")'
1187}
1188
1189function test_not_enough_arguments() {
1190  ERROR=1 run "$one_dep" 'add foo' '//pkg:edit'
1191  assert_err "Too few arguments for command 'add', expected at least 2."
1192}
1193
1194function test_too_many_arguments() {
1195  ERROR=1 run "$one_dep" 'delete foo' '//pkg:edit'
1196  assert_err "Too many arguments for command 'delete', expected at most 0."
1197}
1198
1199function test_package_name_missing() {
1200  ERROR=2 run "$one_dep" 'add deps //dep' ':edit'
1201  assert_err "file not found"
1202}
1203
1204function test_nonexistent_package_name() {
1205  ERROR=2 run "$one_dep" 'add deps //dep' '//doesnt_exist:edit'
1206  assert_err "file not found"
1207}
1208
1209function test_nonexistent_rule_name() {
1210  ERROR=2 run "$one_dep" 'add deps //dep' '//pkg:doesnt_exist'
1211  assert_err "rule 'doesnt_exist' not found"
1212}
1213
1214function test_keep_going() {
1215  ERROR=2 run "$one_dep" -k 'add deps //dep' 'new cc_library edit' '//pkg:doesnt_exist' '//pkg:edit'
1216  assert_err "rule 'doesnt_exist' not found"
1217  assert_err "rule 'edit' already exists"
1218  # Make sure the commands are in the error message.
1219  assert_err "add deps //dep"
1220  assert_err "new cc_library edit"
1221  # Make sure the full targets are in the error message.
1222  assert_err "//pkg:doesnt_exist"
1223  assert_equals 'go_library(
1224    name = "edit",
1225    deps = [
1226        "//buildifier:build",
1227        "//dep",
1228    ],
1229)'
1230}
1231
1232function test_buildifier_missing() {
1233  ERROR=2 run "$one_dep" '--buildifier=doesnt_exist' 'add deps //dep' '//pkg:edit'
1234  assert_err "executable file not found in \$PATH"
1235}
1236
1237function test_buildifier_return_error() {
1238  ERROR=2 run "$one_dep" '--buildifier=false' 'add deps //dep' '//pkg:edit'
1239  assert_err "running buildifier: exit status 1"
1240}
1241
1242function test_add_deps_to_targets_in_same_package() {
1243  in='cc_library(name = "smurf")
1244cc_library(name = "smorf")'
1245  run "$in" 'add deps //foo:bar' //pkg:smurf //pkg:smorf
1246  assert_equals 'cc_library(
1247    name = "smurf",
1248    deps = ["//foo:bar"],
1249)
1250
1251cc_library(
1252    name = "smorf",
1253    deps = ["//foo:bar"],
1254)'
1255}
1256
1257function test_rule_comment() {
1258  in='cc_library(name = "a")'
1259  run "$in" 'comment Hello' //pkg:a
1260  assert_equals '# Hello
1261cc_library(name = "a")'
1262}
1263
1264function test_attribute_comment() {
1265  in='cc_library(
1266    name = "a",
1267    srcs = ["a.cc"],
1268)'
1269  run "$in" 'comment srcs Hello\ World' //pkg:a
1270  assert_equals 'cc_library(
1271    name = "a",
1272    srcs = ["a.cc"],  # Hello World
1273)'
1274}
1275
1276function test_attribute_comment_no_eol() {
1277  in='cc_library(
1278    name = "a",
1279    srcs = ["a.cc"],
1280)'
1281  run "$in" --eol-comments=false 'comment srcs Hello\ World' //pkg:a
1282  assert_equals 'cc_library(
1283    name = "a",
1284    # Hello World
1285    srcs = ["a.cc"],
1286)'
1287}
1288
1289function test_value_comment() {
1290  in='cc_library(
1291    name = "a",
1292    srcs = [
1293        "a.cc",
1294        "b.cc",  # Old
1295    ],
1296)'
1297  run "$in" 'comment srcs a.cc Hello' 'comment srcs b.cc New' //pkg:a
1298  assert_equals 'cc_library(
1299    name = "a",
1300    srcs = [
1301        "a.cc",  # Hello
1302        "b.cc",  # New
1303    ],
1304)'
1305}
1306
1307function test_value_multiline_comment() {
1308  in='cc_library(
1309    name = "a",
1310    srcs = [
1311        "a.cc",
1312        "b.cc",
1313    ],
1314)'
1315  run "$in" 'comment srcs b.cc Just\ a\
1316multiline\ comment' //pkg:a
1317  assert_equals 'cc_library(
1318    name = "a",
1319    srcs = [
1320        "a.cc",
1321        # Just a
1322        # multiline comment
1323        "b.cc",
1324    ],
1325)'
1326  run "$in" 'comment srcs b.cc Another\nmultiline\ comment' //pkg:a
1327  assert_equals 'cc_library(
1328    name = "a",
1329    srcs = [
1330        "a.cc",
1331        # Another
1332        # multiline comment
1333        "b.cc",
1334    ],
1335)'
1336}
1337
1338function test_rule_print_comment() {
1339  in='# Hello
1340cc_library(name = "a")'
1341  ERROR=3 run "$in" 'print_comment' //pkg:a
1342  assert_output 'Hello'
1343}
1344
1345function test_attribute_print_comment() {
1346  in='cc_library(
1347    name = "a",
1348    srcs = ["a.cc"],  # Hello World
1349)'
1350  ERROR=3 run "$in" 'print_comment srcs' //pkg:a
1351  assert_output 'Hello World'
1352}
1353
1354function test_attribute_print_comment_no_eol() {
1355  in='cc_library(
1356    name = "a",
1357    # Hello World
1358    srcs = ["a.cc"],
1359)'
1360  ERROR=3 run "$in" --eol-comments=false 'print_comment srcs' //pkg:a
1361  assert_output 'Hello World'
1362}
1363
1364function test_value_print_comment() {
1365  in='cc_library(
1366    name = "a",
1367    srcs = [
1368        "a.cc",  # World
1369        "b.cc",  # Hello
1370    ],
1371)'
1372  ERROR=3 run "$in" 'print_comment srcs b.cc' 'print_comment srcs a.cc' //pkg:a
1373  assert_output 'Hello
1374World'
1375}
1376
1377function test_value_multiline_print_comment() {
1378  in='cc_library(
1379    name = "a",
1380    srcs = [
1381        "a.cc",
1382        # Just a
1383        # multiline comment
1384        "b.cc",
1385    ],
1386)'
1387  ERROR=3 run "$in" 'print_comment srcs b.cc' //pkg:a
1388  assert_output 'Just a multiline comment'
1389}
1390
1391function test_value_inside_select_print_comment() {
1392  in='cc_library(
1393    name = "a",
1394    srcs = [
1395        "a.cc",  # World
1396        "b.cc",  # Hello
1397    ] + select({
1398        "foo": [
1399            "c.cc",  # hello
1400            "d.cc",  # world
1401        ],
1402    }),
1403)'
1404  ERROR=3 run "$in" 'print_comment srcs c.cc' 'print_comment srcs d.cc' //pkg:a
1405  assert_output 'hello
1406world'
1407}
1408
1409# Test both absolute and relative package names
1410function test_path() {
1411  mkdir -p "java/com/foo/myproject"
1412  echo 'java_library(name = "foo")' > "java/com/foo/myproject/BUILD"
1413
1414  $buildozer --buildifier= 'add deps a' "java/com/foo/myproject:foo"
1415  cd java
1416  $buildozer --buildifier= 'add deps b' "com/foo/myproject:foo"
1417  cd com
1418  $buildozer --buildifier= 'add deps c' "//java/com/foo/myproject:foo"
1419  cd foo
1420  $buildozer --buildifier= 'add deps d' "myproject:foo"
1421  cd myproject
1422  $buildozer --buildifier= 'add deps e' ":foo"
1423
1424  # Check that all dependencies have been added
1425  echo -n 'java_library(name="foo",deps=["a","b","c","d","e",],)' > expected
1426  tr -d ' \n' < "BUILD" > result
1427  diff -u "expected" "result" || fail "Output didn't match"
1428}
1429
1430function setup_file_test() {
1431  mkdir -p "a/pkg1"
1432  mkdir -p "a/pkg2"
1433  cat > a/pkg1/BUILD <<EOF
1434cc_library(name = "foo")
1435cc_library(name = "bar")
1436EOF
1437  cat > a/pkg2/BUILD << EOF
1438cc_library(name = "foo")
1439cc_library(name = "bar")
1440EOF
1441
1442  echo -n "
1443new cc_library baz|//a/pkg1:__pkg__
1444add deps a|//a/pkg1:baz
1445add deps a|a/pkg1:foo
1446add deps x|a/pkg2:foo
1447
1448add deps y|a/pkg2:bar|add deps c|a/pkg1:foo
1449add deps z|a/pkg2:bar
1450add deps a|//a/pkg1:bar
1451add deps b|a/pkg1:foo" > commands
1452}
1453
1454function check_file_test() {
1455  # Check that all dependencies have been added
1456  cat > expected_pkg_1 <<EOF
1457cc_library(
1458    name = "foo",
1459    deps = [
1460        "a",
1461        "b",
1462        "c",
1463        "y",
1464    ],
1465)
1466
1467cc_library(
1468    name = "bar",
1469    deps = ["a"],
1470)
1471
1472cc_library(
1473    name = "baz",
1474    deps = ["a"],
1475)
1476EOF
1477  diff -u expected_pkg_1 a/pkg1/BUILD || fail "Output didn't match"
1478
1479  cat > expected_pkg_2 <<EOF
1480cc_library(
1481    name = "foo",
1482    deps = ["x"],
1483)
1484
1485cc_library(
1486    name = "bar",
1487    deps = [
1488        "c",
1489        "y",
1490        "z",
1491    ],
1492)
1493EOF
1494  diff -u expected_pkg_2 a/pkg2/BUILD || fail "Output didn't match"
1495}
1496
1497# Test reading commands from stdin
1498function test_file() {
1499  setup_file_test
1500  $buildozer --buildifier= -f - < commands
1501  check_file_test
1502
1503  setup_file_test
1504  $buildozer --buildifier= -f commands
1505  check_file_test
1506}
1507
1508# Test for selectively adding to specific rule types
1509function test_add_dep_filtered() {
1510  in='go_library(
1511    name = "edit",
1512    deps = ["//pkg:a"],
1513)'
1514  ERROR=3 run "$in" -types='cc_library' 'add deps //pkg:b' '//pkg:edit'
1515  assert_equals "$in"
1516}
1517
1518function test_add_dep_unfiltered() {
1519  in='cc_library(
1520    name = "edit",
1521    deps = ["//pkg:a"],
1522)'
1523  run "$in" -types='cc_library' 'add deps //pkg:b' '//pkg:edit'
1524  assert_equals 'cc_library(
1525    name = "edit",
1526    deps = [
1527        ":b",
1528        "//pkg:a",
1529    ],
1530)'
1531}
1532
1533function test_add_library_always_unfiltered() {
1534  in='cc_library(
1535    name = "edit",
1536    deps = ["//pkg:a"],
1537)'
1538  run "$in" -types='go_library' 'new cc_library a' '//pkg:__pkg__'
1539  assert_equals 'cc_library(
1540    name = "edit",
1541    deps = ["//pkg:a"],
1542)
1543
1544cc_library(name = "a")'
1545}
1546
1547function test_new_load_after_package() {
1548in='# Comment
1549
1550package(default_visibility = ["//visibility:public"])
1551
1552x(
1553    name="x",
1554    srcs=["x.cc"],
1555)'
1556
1557  run "$in" 'new_load /foo/bar x y z' '//pkg:x'
1558  assert_equals '# Comment
1559
1560load("/foo/bar", "x", "y", "z")
1561
1562package(default_visibility = ["//visibility:public"])
1563
1564x(
1565    name = "x",
1566    srcs = ["x.cc"],
1567)'
1568}
1569
1570
1571function test_new_load_no_package() {
1572in='x(
1573    name="x",
1574    srcs=["x.cc"],
1575)'
1576
1577  run "$in" 'new_load /foo/bar x y z' '//pkg:x'
1578  assert_equals 'load("/foo/bar", "x", "y", "z")
1579
1580x(
1581    name = "x",
1582    srcs = ["x.cc"],
1583)'
1584}
1585
1586
1587function test_new_load_empty_file() {
1588  run '' 'new_load /foo/bar x y z' pkg/BUILD
1589  assert_equals 'load("/foo/bar", "x", "y", "z")'
1590}
1591
1592function test_new_load_only_comments() {
1593in='# Just comments
1594# And more comments'
1595
1596  run "$in" 'new_load /foo/bar x y z' pkg/BUILD
1597  assert_equals '# Just comments
1598# And more comments
1599
1600load("/foo/bar", "x", "y", "z")'
1601}
1602
1603function test_new_load_existing() {
1604in='load("/foo/bar", "y")
1605'
1606
1607  run "$in" 'new_load /foo/bar z x y' pkg/BUILD
1608  assert_equals 'load("/foo/bar", "x", "y", "z")'
1609}
1610
1611function test_new_load_existing_multiple() {
1612in='load("/foo/bar", "x")
1613load("/foo/bar", "y")
1614'
1615
1616  run "$in" 'new_load /foo/bar x y z' pkg/BUILD
1617  assert_equals 'load("/foo/bar", "x")
1618load("/foo/bar", "y", "z")'
1619}
1620
1621function test_new_load_wrong_location() {
1622in='load("/foo/bar", "x")
1623'
1624
1625  run "$in" 'new_load /baz/bam y z' pkg/BUILD
1626  assert_equals 'load("/baz/bam", "y", "z")
1627load("/foo/bar", "x")'
1628}
1629
1630function test_print_attribute_value_with_spaces() {
1631  in='cc_test(name = "a", deprecation = "one two three")'
1632  ERROR=3 run "$in" 'print deprecation' '//pkg:a'
1633  assert_output '"one two three"'
1634}
1635
1636function test_insert_into_variable() {
1637in='some_var = ["a"]
1638some_rule(name="r", deps=some_var)'
1639
1640  run "$in" --edit-variables 'add deps b' '//pkg:r'
1641  assert_equals 'some_var = [
1642    "a",
1643    "b",
1644]
1645
1646some_rule(
1647    name = "r",
1648    deps = some_var,
1649)'
1650}
1651
1652function test_insert_into_variable_by_adding() {
1653in='some_var = glob(["x"])
1654some_rule(name="r", deps=some_var)'
1655
1656  run "$in" --edit-variables "add deps b" '//pkg:r'
1657  assert_equals 'some_var = glob(["x"]) + ["b"]
1658
1659some_rule(
1660    name = "r",
1661    deps = some_var,
1662)'
1663}
1664
1665function test_insert_into_same_variable_twice() {
1666in='some_var = ["a"]
1667some_rule(name="r1", deps=some_var)
1668some_rule(name="r2", deps=some_var)'
1669
1670  run "$in" --edit-variables "add deps b" '//pkg:r1' '//pkg:r2'
1671  assert_equals 'some_var = [
1672    "a",
1673    "b",
1674]
1675
1676some_rule(
1677    name = "r1",
1678    deps = some_var,
1679)
1680
1681some_rule(
1682    name = "r2",
1683    deps = some_var,
1684)'
1685}
1686
1687function test_pkg_recursive_wildcard() {
1688mkdir -p foo/bar/baz
1689mkdir -p foo/abc
1690
1691cat > foo/BUILD <<EOF
1692matching_rule(name = "r1", deps = [":bar"])
1693EOF
1694cat > foo/bar/BUILD <<EOF
1695non_matching_rule(name = "r2", deps = [":bar"])
1696EOF
1697cat > foo/bar/baz/BUILD <<EOF
1698matching_rule(name = "r3", deps = [":bar"])
1699EOF
1700cat > foo/abc/BUILD <<EOF
1701matching_rule(name = "r4", deps = [":bar"])
1702EOF
1703
1704run_with_current_workspace "$buildozer --buildifier=" "add deps new_dep" "//foo/...:%matching_rule"
1705assert_no_err "rule '%matching_rule' not found"
1706
1707assert_equals 'matching_rule(
1708    name = "r1",
1709    deps = [
1710        "new_dep",
1711        ":bar",
1712    ],
1713)' foo
1714
1715assert_equals 'non_matching_rule(name = "r2", deps = [":bar"])' foo/bar
1716
1717assert_equals 'matching_rule(
1718    name = "r3",
1719    deps = [
1720        "new_dep",
1721        ":bar",
1722    ],
1723)' foo/bar/baz
1724
1725assert_equals 'matching_rule(
1726    name = "r4",
1727    deps = [
1728        "new_dep",
1729        ":bar",
1730    ],
1731)' foo/abc
1732}
1733
1734function test_add_dep_string() {
1735  # Add a string without quotes, a quoted string (should be unquoted automatically)
1736  # and a quoted string with quotes inside (should be unquoted just once).
1737  run "$one_dep" 'add deps //foo "//bar" "\"//baz\""' '//pkg:edit'
1738  assert_equals 'go_library(
1739    name = "edit",
1740    deps = [
1741        "\"//baz\"",
1742        "//bar",
1743        "//buildifier:build",
1744        "//foo",
1745    ],
1746)'
1747}
1748
1749function test_remove_dep_string() {
1750  # Remove quoted and unquoted strings to make sure that `add` and `remove`
1751  # unquote them equally
1752  run "$quoted_deps" 'remove deps //foo "//bar" "\"//baz\""' '//pkg:edit'
1753  assert_equals 'go_library(
1754    name = "edit",
1755    deps = ["//buildifier:build"],
1756)'
1757}
1758
1759function test_set_config_string() {
1760  run "$one_dep" 'set config "foo"' '//pkg:edit'
1761  assert_equals 'go_library(
1762    name = "edit",
1763    config = "foo",
1764    deps = ["//buildifier:build"],
1765)'
1766}
1767
1768run_suite "buildozer tests"
1769