github.com/bazelbuild/bazel-gazelle@v0.36.1-0.20240520142334-61b277ba6fed/cmd/gazelle/integration_test.go (about) 1 /* Copyright 2017 The Bazel Authors. All rights reserved. 2 3 Licensed under the Apache License, Version 2.0 (the "License"); 4 you may not use this file except in compliance with the License. 5 You may obtain a copy of the License at 6 7 http://www.apache.org/licenses/LICENSE-2.0 8 9 Unless required by applicable law or agreed to in writing, software 10 distributed under the License is distributed on an "AS IS" BASIS, 11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 See the License for the specific language governing permissions and 13 limitations under the License. 14 */ 15 16 // This file contains integration tests for all of Gazelle. It's meant to test 17 // common usage patterns and check for errors that are difficult to test in 18 // unit tests. 19 20 package main 21 22 import ( 23 "bytes" 24 "flag" 25 "log" 26 "os" 27 "path/filepath" 28 "strings" 29 "testing" 30 31 "github.com/bazelbuild/bazel-gazelle/config" 32 "github.com/bazelbuild/bazel-gazelle/internal/wspace" 33 "github.com/bazelbuild/bazel-gazelle/testtools" 34 "github.com/google/go-cmp/cmp" 35 ) 36 37 // skipIfWorkspaceVisible skips the test if the WORKSPACE file for the 38 // repository is visible. This happens in newer Bazel versions when tests 39 // are run without sandboxing, since temp directories may be inside the 40 // exec root. 41 func skipIfWorkspaceVisible(t *testing.T, dir string) { 42 if parent, err := wspace.FindRepoRoot(dir); err == nil { 43 t.Skipf("WORKSPACE visible in parent %q of tmp %q", parent, dir) 44 } 45 } 46 47 func runGazelle(wd string, args []string) error { 48 return run(wd, args) 49 } 50 51 // TestHelp checks that help commands do not panic due to nil flag values. 52 // Verifies #256. 53 func TestHelp(t *testing.T) { 54 for _, args := range [][]string{ 55 {"help"}, 56 {"fix", "-h"}, 57 {"update", "-h"}, 58 {"update-repos", "-h"}, 59 } { 60 t.Run(args[0], func(t *testing.T) { 61 if err := runGazelle(".", args); err == nil { 62 t.Errorf("%s: got success, want flag.ErrHelp", args[0]) 63 } else if err != flag.ErrHelp { 64 t.Errorf("%s: got %v, want flag.ErrHelp", args[0], err) 65 } 66 }) 67 } 68 } 69 70 func TestNoRepoRootOrWorkspace(t *testing.T) { 71 dir, cleanup := testtools.CreateFiles(t, nil) 72 defer cleanup() 73 skipIfWorkspaceVisible(t, dir) 74 want := "-repo_root not specified" 75 if err := runGazelle(dir, nil); err == nil { 76 t.Fatalf("got success; want %q", want) 77 } else if !strings.Contains(err.Error(), want) { 78 t.Fatalf("got %q; want %q", err, want) 79 } 80 } 81 82 func TestNoGoPrefixArgOrRule(t *testing.T) { 83 dir, cleanup := testtools.CreateFiles(t, []testtools.FileSpec{ 84 {Path: "WORKSPACE", Content: ""}, 85 {Path: "hello.go", Content: "package hello"}, 86 }) 87 defer cleanup() 88 buf := new(bytes.Buffer) 89 log.SetOutput(buf) 90 defer log.SetOutput(os.Stderr) 91 if err := runGazelle(dir, nil); err != nil { 92 t.Fatalf("got %#v; want success", err) 93 } 94 want := "go prefix is not set" 95 if !strings.Contains(buf.String(), want) { 96 t.Errorf("log does not contain %q\n--begin--\n%s--end--\n", want, buf.String()) 97 } 98 } 99 100 // TestSelectLabelsSorted checks that string lists in srcs and deps are sorted 101 // using buildifier order, even if they are inside select expressions. 102 // This applies to both new and existing lists and should preserve comments. 103 // buildifier does not do this yet bazelbuild/buildtools#122, so we do this 104 // in addition to calling build.Rewrite. 105 func TestSelectLabelsSorted(t *testing.T) { 106 dir, cleanup := testtools.CreateFiles(t, []testtools.FileSpec{ 107 {Path: "WORKSPACE"}, 108 { 109 Path: "BUILD", 110 Content: ` 111 load("@io_bazel_rules_go//go:def.bzl", "go_library") 112 113 go_library( 114 name = "go_default_library", 115 srcs = select({ 116 "@io_bazel_rules_go//go/platform:linux": [ 117 # foo comment 118 "foo.go", # side comment 119 # bar comment 120 "bar.go", 121 ], 122 "//conditions:default": [], 123 }), 124 importpath = "example.com/foo", 125 ) 126 `, 127 }, 128 { 129 Path: "foo.go", 130 Content: ` 131 // +build linux 132 133 package foo 134 135 import ( 136 _ "example.com/foo/outer" 137 _ "example.com/foo/outer/inner" 138 _ "github.com/jr_hacker/tools" 139 ) 140 `, 141 }, 142 { 143 Path: "foo_android_build_tag.go", 144 Content: ` 145 // +build android 146 147 package foo 148 149 import ( 150 _ "example.com/foo/outer_android_build_tag" 151 ) 152 `, 153 }, 154 { 155 Path: "foo_android.go", 156 Content: ` 157 package foo 158 159 import ( 160 _ "example.com/foo/outer_android_suffix" 161 ) 162 `, 163 }, 164 { 165 Path: "bar.go", 166 Content: `// +build linux 167 168 package foo 169 `, 170 }, 171 {Path: "outer/outer.go", Content: "package outer"}, 172 {Path: "outer_android_build_tag/outer.go", Content: "package outer_android_build_tag"}, 173 {Path: "outer_android_suffix/outer.go", Content: "package outer_android_suffix"}, 174 {Path: "outer/inner/inner.go", Content: "package inner"}, 175 }) 176 want := `load("@io_bazel_rules_go//go:def.bzl", "go_library") 177 178 go_library( 179 name = "go_default_library", 180 srcs = [ 181 # bar comment 182 "bar.go", 183 # foo comment 184 "foo.go", # side comment 185 "foo_android.go", 186 "foo_android_build_tag.go", 187 ], 188 importpath = "example.com/foo", 189 visibility = ["//visibility:public"], 190 deps = select({ 191 "@io_bazel_rules_go//go/platform:android": [ 192 "//outer:go_default_library", 193 "//outer/inner:go_default_library", 194 "//outer_android_build_tag:go_default_library", 195 "//outer_android_suffix:go_default_library", 196 "@com_github_jr_hacker_tools//:go_default_library", 197 ], 198 "@io_bazel_rules_go//go/platform:linux": [ 199 "//outer:go_default_library", 200 "//outer/inner:go_default_library", 201 "@com_github_jr_hacker_tools//:go_default_library", 202 ], 203 "//conditions:default": [], 204 }), 205 ) 206 ` 207 defer cleanup() 208 209 if err := runGazelle(dir, []string{"-go_prefix", "example.com/foo"}); err != nil { 210 t.Fatal(err) 211 } 212 if got, err := os.ReadFile(filepath.Join(dir, "BUILD")); err != nil { 213 t.Fatal(err) 214 } else if string(got) != want { 215 t.Fatalf("got %s ; want %s", string(got), want) 216 } 217 } 218 219 func TestFixAndUpdateChanges(t *testing.T) { 220 files := []testtools.FileSpec{ 221 {Path: "WORKSPACE"}, 222 { 223 Path: "BUILD", 224 Content: `load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_prefix") 225 load("@io_bazel_rules_go//go:def.bzl", "cgo_library", "go_test") 226 227 go_prefix("example.com/foo") 228 229 go_library( 230 name = "go_default_library", 231 srcs = [ 232 "extra.go", 233 "pure.go", 234 ], 235 library = ":cgo_default_library", 236 visibility = ["//visibility:default"], 237 ) 238 239 cgo_library( 240 name = "cgo_default_library", 241 srcs = ["cgo.go"], 242 ) 243 `, 244 }, 245 { 246 Path: "pure.go", 247 Content: "package foo", 248 }, 249 { 250 Path: "cgo.go", 251 Content: `package foo 252 253 import "C" 254 `, 255 }, 256 } 257 258 cases := []struct { 259 cmd, want string 260 }{ 261 { 262 cmd: "update", 263 want: `load("@io_bazel_rules_go//go:def.bzl", "cgo_library", "go_library", "go_prefix") 264 265 go_prefix("example.com/foo") 266 267 go_library( 268 name = "go_default_library", 269 srcs = [ 270 "cgo.go", 271 "pure.go", 272 ], 273 cgo = True, 274 importpath = "example.com/foo", 275 visibility = ["//visibility:default"], 276 ) 277 278 cgo_library( 279 name = "cgo_default_library", 280 srcs = ["cgo.go"], 281 ) 282 `, 283 }, { 284 cmd: "fix", 285 want: `load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_prefix") 286 287 go_prefix("example.com/foo") 288 289 go_library( 290 name = "go_default_library", 291 srcs = [ 292 "cgo.go", 293 "pure.go", 294 ], 295 cgo = True, 296 importpath = "example.com/foo", 297 visibility = ["//visibility:default"], 298 ) 299 `, 300 }, 301 } 302 303 for _, c := range cases { 304 t.Run(c.cmd, func(t *testing.T) { 305 dir, cleanup := testtools.CreateFiles(t, files) 306 defer cleanup() 307 308 if err := runGazelle(dir, []string{c.cmd}); err != nil { 309 t.Fatal(err) 310 } 311 if got, err := os.ReadFile(filepath.Join(dir, "BUILD")); err != nil { 312 t.Fatal(err) 313 } else if string(got) != c.want { 314 t.Fatalf("got %s ; want %s", string(got), c.want) 315 } 316 }) 317 } 318 } 319 320 func TestFixUnlinkedCgoLibrary(t *testing.T) { 321 files := []testtools.FileSpec{ 322 {Path: "WORKSPACE"}, 323 { 324 Path: "BUILD", 325 Content: `load("@io_bazel_rules_go//go:def.bzl", "cgo_library", "go_library") 326 327 cgo_library( 328 name = "cgo_default_library", 329 srcs = ["cgo.go"], 330 ) 331 332 go_library( 333 name = "go_default_library", 334 srcs = ["pure.go"], 335 importpath = "example.com/foo", 336 visibility = ["//visibility:public"], 337 ) 338 `, 339 }, 340 { 341 Path: "pure.go", 342 Content: "package foo", 343 }, 344 } 345 346 dir, cleanup := testtools.CreateFiles(t, files) 347 defer cleanup() 348 349 want := `load("@io_bazel_rules_go//go:def.bzl", "go_library") 350 351 go_library( 352 name = "go_default_library", 353 srcs = ["pure.go"], 354 importpath = "example.com/foo", 355 visibility = ["//visibility:public"], 356 ) 357 ` 358 if err := runGazelle(dir, []string{"fix", "-go_prefix", "example.com/foo"}); err != nil { 359 t.Fatal(err) 360 } 361 if got, err := os.ReadFile(filepath.Join(dir, "BUILD")); err != nil { 362 t.Fatal(err) 363 } else if string(got) != want { 364 t.Fatalf("got %s ; want %s", string(got), want) 365 } 366 } 367 368 // TestMultipleDirectories checks that all directories in a repository are 369 // indexed but only directories listed on the command line are updated. 370 func TestMultipleDirectories(t *testing.T) { 371 files := []testtools.FileSpec{ 372 {Path: "WORKSPACE"}, 373 { 374 Path: "a/BUILD.bazel", 375 Content: `# This file shouldn't be modified. 376 load("@io_bazel_rules_go//go:def.bzl", "go_library") 377 378 go_library( 379 name = "go_default_library", 380 srcs = ["a.go"], 381 importpath = "example.com/foo/x", 382 ) 383 `, 384 }, 385 { 386 Path: "a/a.go", 387 Content: "package a", 388 }, 389 { 390 Path: "b/b.go", 391 Content: ` 392 package b 393 394 import _ "example.com/foo/x" 395 `, 396 }, 397 } 398 dir, cleanup := testtools.CreateFiles(t, files) 399 defer cleanup() 400 401 args := []string{"-go_prefix", "example.com/foo", "b"} 402 if err := runGazelle(dir, args); err != nil { 403 t.Fatal(err) 404 } 405 406 testtools.CheckFiles(t, dir, []testtools.FileSpec{ 407 files[1], // should not change 408 { 409 Path: "b/BUILD.bazel", 410 Content: `load("@io_bazel_rules_go//go:def.bzl", "go_library") 411 412 go_library( 413 name = "go_default_library", 414 srcs = ["b.go"], 415 importpath = "example.com/foo/b", 416 visibility = ["//visibility:public"], 417 deps = ["//a:go_default_library"], 418 ) 419 `, 420 }, 421 }) 422 } 423 424 func TestErrorOutsideWorkspace(t *testing.T) { 425 files := []testtools.FileSpec{ 426 {Path: "a/"}, 427 {Path: "b/"}, 428 } 429 dir, cleanup := testtools.CreateFiles(t, files) 430 defer cleanup() 431 skipIfWorkspaceVisible(t, dir) 432 433 cases := []struct { 434 name, dir, want string 435 args []string 436 }{ 437 { 438 name: "outside workspace", 439 dir: dir, 440 args: nil, 441 want: "WORKSPACE cannot be found", 442 }, { 443 name: "outside repo_root", 444 dir: filepath.Join(dir, "a"), 445 args: []string{"-repo_root", filepath.Join(dir, "b")}, 446 want: "not a subdirectory of repo root", 447 }, 448 } 449 for _, c := range cases { 450 t.Run(c.name, func(t *testing.T) { 451 if err := runGazelle(c.dir, c.args); err == nil { 452 t.Fatalf("got success; want %q", c.want) 453 } else if !strings.Contains(err.Error(), c.want) { 454 t.Fatalf("got %q; want %q", err, c.want) 455 } 456 }) 457 } 458 } 459 460 func TestBuildFileNameIgnoresBuild(t *testing.T) { 461 files := []testtools.FileSpec{ 462 {Path: "WORKSPACE"}, 463 {Path: "BUILD/"}, 464 { 465 Path: "a/BUILD", 466 Content: "!!! parse error", 467 }, 468 { 469 Path: "a.go", 470 Content: "package a", 471 }, 472 } 473 dir, cleanup := testtools.CreateFiles(t, files) 474 defer cleanup() 475 476 args := []string{"-go_prefix", "example.com/foo", "-build_file_name", "BUILD.bazel"} 477 if err := runGazelle(dir, args); err != nil { 478 t.Fatal(err) 479 } 480 if _, err := os.Stat(filepath.Join(dir, "BUILD.bazel")); err != nil { 481 t.Errorf("BUILD.bazel not created: %v", err) 482 } 483 } 484 485 func TestExternalVendor(t *testing.T) { 486 files := []testtools.FileSpec{ 487 { 488 Path: "WORKSPACE", 489 Content: `workspace(name = "banana")`, 490 }, { 491 Path: "a.go", 492 Content: `package foo 493 494 import _ "golang.org/x/bar" 495 `, 496 }, { 497 Path: "vendor/golang.org/x/bar/bar.go", 498 Content: `package bar 499 500 import _ "golang.org/x/baz" 501 `, 502 }, { 503 Path: "vendor/golang.org/x/baz/baz.go", 504 Content: "package baz", 505 }, 506 } 507 dir, cleanup := testtools.CreateFiles(t, files) 508 defer cleanup() 509 510 args := []string{"-go_prefix", "example.com/foo", "-external", "vendored"} 511 if err := runGazelle(dir, args); err != nil { 512 t.Fatal(err) 513 } 514 515 testtools.CheckFiles(t, dir, []testtools.FileSpec{ 516 { 517 Path: config.DefaultValidBuildFileNames[0], 518 Content: `load("@io_bazel_rules_go//go:def.bzl", "go_library") 519 520 go_library( 521 name = "foo", 522 srcs = ["a.go"], 523 importpath = "example.com/foo", 524 visibility = ["//visibility:public"], 525 deps = ["//vendor/golang.org/x/bar"], 526 ) 527 `, 528 }, { 529 Path: "vendor/golang.org/x/bar/" + config.DefaultValidBuildFileNames[0], 530 Content: `load("@io_bazel_rules_go//go:def.bzl", "go_library") 531 532 go_library( 533 name = "bar", 534 srcs = ["bar.go"], 535 importmap = "example.com/foo/vendor/golang.org/x/bar", 536 importpath = "golang.org/x/bar", 537 visibility = ["//visibility:public"], 538 deps = ["//vendor/golang.org/x/baz"], 539 ) 540 `, 541 }, 542 }) 543 } 544 545 func TestMigrateProtoRules(t *testing.T) { 546 files := []testtools.FileSpec{ 547 {Path: "WORKSPACE"}, 548 { 549 Path: config.DefaultValidBuildFileNames[0], 550 Content: ` 551 load("@io_bazel_rules_go//proto:go_proto_library.bzl", "go_proto_library") 552 553 filegroup( 554 name = "go_default_library_protos", 555 srcs = ["foo.proto"], 556 visibility = ["//visibility:public"], 557 ) 558 559 go_proto_library( 560 name = "go_default_library", 561 srcs = [":go_default_library_protos"], 562 ) 563 `, 564 }, 565 { 566 Path: "foo.proto", 567 Content: `syntax = "proto3"; 568 569 option go_package = "example.com/repo"; 570 `, 571 }, 572 { 573 Path: "foo.pb.go", 574 Content: `package repo`, 575 }, 576 } 577 578 for _, tc := range []struct { 579 args []string 580 want string 581 }{ 582 { 583 args: []string{"update", "-go_prefix", "example.com/repo"}, 584 want: ` 585 load("@io_bazel_rules_go//proto:go_proto_library.bzl", "go_proto_library") 586 587 filegroup( 588 name = "go_default_library_protos", 589 srcs = ["foo.proto"], 590 visibility = ["//visibility:public"], 591 ) 592 593 go_proto_library( 594 name = "go_default_library", 595 srcs = [":go_default_library_protos"], 596 ) 597 `, 598 }, { 599 args: []string{"fix", "-go_prefix", "example.com/repo"}, 600 want: ` 601 load("@io_bazel_rules_go//go:def.bzl", "go_library") 602 load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") 603 load("@rules_proto//proto:defs.bzl", "proto_library") 604 605 proto_library( 606 name = "repo_proto", 607 srcs = ["foo.proto"], 608 visibility = ["//visibility:public"], 609 ) 610 611 go_proto_library( 612 name = "repo_go_proto", 613 importpath = "example.com/repo", 614 proto = ":repo_proto", 615 visibility = ["//visibility:public"], 616 ) 617 618 go_library( 619 name = "go_default_library", 620 embed = [":repo_go_proto"], 621 importpath = "example.com/repo", 622 visibility = ["//visibility:public"], 623 ) 624 `, 625 }, 626 } { 627 t.Run(tc.args[0], func(t *testing.T) { 628 dir, cleanup := testtools.CreateFiles(t, files) 629 defer cleanup() 630 631 if err := runGazelle(dir, tc.args); err != nil { 632 t.Fatal(err) 633 } 634 635 testtools.CheckFiles(t, dir, []testtools.FileSpec{{ 636 Path: config.DefaultValidBuildFileNames[0], 637 Content: tc.want, 638 }}) 639 }) 640 } 641 } 642 643 func TestRemoveProtoDeletesRules(t *testing.T) { 644 files := []testtools.FileSpec{ 645 {Path: "WORKSPACE"}, 646 { 647 Path: config.DefaultValidBuildFileNames[0], 648 Content: ` 649 load("@rules_proto//proto:defs.bzl", "proto_library") 650 load("@io_bazel_rules_go//go:def.bzl", "go_library") 651 load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") 652 653 filegroup( 654 name = "go_default_library_protos", 655 srcs = ["foo.proto"], 656 visibility = ["//visibility:public"], 657 ) 658 659 proto_library( 660 name = "repo_proto", 661 srcs = ["foo.proto"], 662 visibility = ["//visibility:public"], 663 ) 664 665 go_proto_library( 666 name = "repo_go_proto", 667 importpath = "example.com/repo", 668 proto = ":repo_proto", 669 visibility = ["//visibility:public"], 670 ) 671 672 go_library( 673 name = "go_default_library", 674 srcs = ["extra.go"], 675 embed = [":repo_go_proto"], 676 importpath = "example.com/repo", 677 visibility = ["//visibility:public"], 678 ) 679 `, 680 }, 681 { 682 Path: "extra.go", 683 Content: `package repo`, 684 }, 685 } 686 dir, cleanup := testtools.CreateFiles(t, files) 687 defer cleanup() 688 689 args := []string{"fix", "-go_prefix", "example.com/repo"} 690 if err := runGazelle(dir, args); err != nil { 691 t.Fatal(err) 692 } 693 694 testtools.CheckFiles(t, dir, []testtools.FileSpec{{ 695 Path: config.DefaultValidBuildFileNames[0], 696 Content: ` 697 load("@io_bazel_rules_go//go:def.bzl", "go_library") 698 699 go_library( 700 name = "go_default_library", 701 srcs = ["extra.go"], 702 importpath = "example.com/repo", 703 visibility = ["//visibility:public"], 704 ) 705 `, 706 }}) 707 } 708 709 func TestAddServiceConvertsToGrpc(t *testing.T) { 710 files := []testtools.FileSpec{ 711 {Path: "WORKSPACE"}, 712 { 713 Path: config.DefaultValidBuildFileNames[0], 714 Content: ` 715 load("@io_bazel_rules_go//go:def.bzl", "go_library") 716 load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") 717 load("@rules_proto//proto:defs.bzl", "proto_library") 718 719 proto_library( 720 name = "repo_proto", 721 srcs = ["foo.proto"], 722 visibility = ["//visibility:public"], 723 ) 724 725 go_proto_library( 726 name = "repo_go_proto", 727 importpath = "example.com/repo", 728 proto = ":repo_proto", 729 visibility = ["//visibility:public"], 730 ) 731 732 go_library( 733 name = "go_default_library", 734 embed = [":repo_go_proto"], 735 importpath = "example.com/repo", 736 visibility = ["//visibility:public"], 737 ) 738 `, 739 }, 740 { 741 Path: "foo.proto", 742 Content: `syntax = "proto3"; 743 744 option go_package = "example.com/repo"; 745 746 service TestService {} 747 `, 748 }, 749 } 750 751 dir, cleanup := testtools.CreateFiles(t, files) 752 defer cleanup() 753 754 args := []string{"-go_prefix", "example.com/repo"} 755 if err := runGazelle(dir, args); err != nil { 756 t.Fatal(err) 757 } 758 759 testtools.CheckFiles(t, dir, []testtools.FileSpec{{ 760 Path: config.DefaultValidBuildFileNames[0], 761 Content: ` 762 load("@io_bazel_rules_go//go:def.bzl", "go_library") 763 load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") 764 load("@rules_proto//proto:defs.bzl", "proto_library") 765 766 proto_library( 767 name = "repo_proto", 768 srcs = ["foo.proto"], 769 visibility = ["//visibility:public"], 770 ) 771 772 go_proto_library( 773 name = "repo_go_proto", 774 compilers = ["@io_bazel_rules_go//proto:go_grpc"], 775 importpath = "example.com/repo", 776 proto = ":repo_proto", 777 visibility = ["//visibility:public"], 778 ) 779 780 go_library( 781 name = "go_default_library", 782 embed = [":repo_go_proto"], 783 importpath = "example.com/repo", 784 visibility = ["//visibility:public"], 785 ) 786 `, 787 }}) 788 } 789 790 func TestProtoImportPrefix(t *testing.T) { 791 files := []testtools.FileSpec{ 792 {Path: "WORKSPACE"}, 793 { 794 Path: config.DefaultValidBuildFileNames[0], 795 Content: ` 796 load("@io_bazel_rules_go//go:def.bzl", "go_library") 797 load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") 798 load("@rules_proto//proto:defs.bzl", "proto_library") 799 800 proto_library( 801 name = "foo_proto", 802 srcs = ["foo.proto"], 803 visibility = ["//visibility:public"], 804 ) 805 806 go_proto_library( 807 name = "repo_go_proto", 808 importpath = "example.com/repo", 809 proto = ":foo_proto", 810 visibility = ["//visibility:public"], 811 ) 812 813 go_library( 814 name = "go_default_library", 815 embed = [":repo_go_proto"], 816 importpath = "example.com/repo", 817 visibility = ["//visibility:public"], 818 ) 819 `, 820 }, 821 { 822 Path: "foo.proto", 823 Content: `syntax = "proto3";`, 824 }, 825 } 826 827 dir, cleanup := testtools.CreateFiles(t, files) 828 defer cleanup() 829 830 args := []string{ 831 "update", "-go_prefix", "example.com/repo", 832 "-proto_import_prefix", "/bar", 833 } 834 if err := runGazelle(dir, args); err != nil { 835 t.Fatal(err) 836 } 837 838 testtools.CheckFiles(t, dir, []testtools.FileSpec{{ 839 Path: config.DefaultValidBuildFileNames[0], 840 Content: ` 841 load("@io_bazel_rules_go//go:def.bzl", "go_library") 842 load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") 843 load("@rules_proto//proto:defs.bzl", "proto_library") 844 845 proto_library( 846 name = "foo_proto", 847 srcs = ["foo.proto"], 848 import_prefix = "/bar", 849 visibility = ["//visibility:public"], 850 ) 851 852 go_proto_library( 853 name = "repo_go_proto", 854 importpath = "example.com/repo", 855 proto = ":foo_proto", 856 visibility = ["//visibility:public"], 857 ) 858 859 go_library( 860 name = "go_default_library", 861 embed = [":repo_go_proto"], 862 importpath = "example.com/repo", 863 visibility = ["//visibility:public"], 864 ) 865 `, 866 }}) 867 } 868 869 func TestEmptyGoPrefix(t *testing.T) { 870 files := []testtools.FileSpec{ 871 {Path: "WORKSPACE"}, 872 { 873 Path: "foo/foo.go", 874 Content: "package foo", 875 }, 876 { 877 Path: "bar/bar.go", 878 Content: ` 879 package bar 880 881 import ( 882 _ "fmt" 883 _ "foo" 884 ) 885 `, 886 }, 887 } 888 889 dir, cleanup := testtools.CreateFiles(t, files) 890 defer cleanup() 891 892 args := []string{"-go_prefix", ""} 893 if err := runGazelle(dir, args); err != nil { 894 t.Fatal(err) 895 } 896 897 testtools.CheckFiles(t, dir, []testtools.FileSpec{{ 898 Path: filepath.Join("bar", config.DefaultValidBuildFileNames[0]), 899 Content: ` 900 load("@io_bazel_rules_go//go:def.bzl", "go_library") 901 902 go_library( 903 name = "bar", 904 srcs = ["bar.go"], 905 importpath = "bar", 906 visibility = ["//visibility:public"], 907 deps = ["//foo"], 908 ) 909 `, 910 }}) 911 } 912 913 // TestResolveKeptImportpath checks that Gazelle can resolve dependencies 914 // against a library with a '# keep' comment on its importpath attribute 915 // when the importpath doesn't match what Gazelle would infer. 916 func TestResolveKeptImportpath(t *testing.T) { 917 files := []testtools.FileSpec{ 918 {Path: "WORKSPACE"}, 919 { 920 Path: "foo/foo.go", 921 Content: ` 922 package foo 923 924 import _ "example.com/alt/baz" 925 `, 926 }, 927 { 928 Path: "bar/BUILD.bazel", 929 Content: `load("@io_bazel_rules_go//go:def.bzl", "go_library") 930 931 go_library( 932 name = "go_default_library", 933 srcs = ["bar.go"], 934 importpath = "example.com/alt/baz", # keep 935 visibility = ["//visibility:public"], 936 ) 937 `, 938 }, 939 { 940 Path: "bar/bar.go", 941 Content: "package bar", 942 }, 943 } 944 945 dir, cleanup := testtools.CreateFiles(t, files) 946 defer cleanup() 947 948 args := []string{"-go_prefix", "example.com/repo"} 949 if err := runGazelle(dir, args); err != nil { 950 t.Fatal(err) 951 } 952 953 testtools.CheckFiles(t, dir, []testtools.FileSpec{ 954 { 955 Path: "foo/BUILD.bazel", 956 Content: ` 957 load("@io_bazel_rules_go//go:def.bzl", "go_library") 958 959 go_library( 960 name = "go_default_library", 961 srcs = ["foo.go"], 962 importpath = "example.com/repo/foo", 963 visibility = ["//visibility:public"], 964 deps = ["//bar:go_default_library"], 965 ) 966 `, 967 }, { 968 Path: "bar/BUILD.bazel", 969 Content: `load("@io_bazel_rules_go//go:def.bzl", "go_library") 970 971 go_library( 972 name = "go_default_library", 973 srcs = ["bar.go"], 974 importpath = "example.com/alt/baz", # keep 975 visibility = ["//visibility:public"], 976 ) 977 `, 978 }, 979 }) 980 } 981 982 // TestResolveVendorSubdirectory checks that Gazelle can resolve libraries 983 // in a vendor directory which is not at the repository root. 984 func TestResolveVendorSubdirectory(t *testing.T) { 985 files := []testtools.FileSpec{ 986 {Path: "WORKSPACE"}, 987 { 988 Path: "sub/vendor/example.com/foo/foo.go", 989 Content: "package foo", 990 }, 991 { 992 Path: "sub/bar/bar.go", 993 Content: ` 994 package bar 995 996 import _ "example.com/foo" 997 `, 998 }, 999 } 1000 dir, cleanup := testtools.CreateFiles(t, files) 1001 defer cleanup() 1002 1003 args := []string{"-go_prefix", "example.com/repo"} 1004 if err := runGazelle(dir, args); err != nil { 1005 t.Fatal(err) 1006 } 1007 1008 testtools.CheckFiles(t, dir, []testtools.FileSpec{ 1009 { 1010 Path: "sub/vendor/example.com/foo/BUILD.bazel", 1011 Content: ` 1012 load("@io_bazel_rules_go//go:def.bzl", "go_library") 1013 1014 go_library( 1015 name = "foo", 1016 srcs = ["foo.go"], 1017 importmap = "example.com/repo/sub/vendor/example.com/foo", 1018 importpath = "example.com/foo", 1019 visibility = ["//visibility:public"], 1020 ) 1021 `, 1022 }, { 1023 Path: "sub/bar/BUILD.bazel", 1024 Content: ` 1025 load("@io_bazel_rules_go//go:def.bzl", "go_library") 1026 1027 go_library( 1028 name = "bar", 1029 srcs = ["bar.go"], 1030 importpath = "example.com/repo/sub/bar", 1031 visibility = ["//visibility:public"], 1032 deps = ["//sub/vendor/example.com/foo"], 1033 ) 1034 `, 1035 }, 1036 }) 1037 } 1038 1039 // TestDeleteProtoWithDeps checks that Gazelle will delete proto rules with 1040 // dependencies after the proto sources are removed. 1041 func TestDeleteProtoWithDeps(t *testing.T) { 1042 files := []testtools.FileSpec{ 1043 {Path: "WORKSPACE"}, 1044 { 1045 Path: "foo/BUILD.bazel", 1046 Content: ` 1047 load("@rules_proto//proto:defs.bzl", "proto_library") 1048 load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") 1049 load("@io_bazel_rules_go//go:def.bzl", "go_library") 1050 1051 go_library( 1052 name = "go_default_library", 1053 srcs = ["extra.go"], 1054 embed = [":scratch_go_proto"], 1055 importpath = "example.com/repo/foo", 1056 visibility = ["//visibility:public"], 1057 ) 1058 1059 proto_library( 1060 name = "foo_proto", 1061 srcs = ["foo.proto"], 1062 visibility = ["//visibility:public"], 1063 deps = ["//foo/bar:bar_proto"], 1064 ) 1065 1066 go_proto_library( 1067 name = "foo_go_proto", 1068 importpath = "example.com/repo/foo", 1069 proto = ":foo_proto", 1070 visibility = ["//visibility:public"], 1071 deps = ["//foo/bar:go_default_library"], 1072 ) 1073 `, 1074 }, 1075 { 1076 Path: "foo/extra.go", 1077 Content: "package foo", 1078 }, 1079 { 1080 Path: "foo/bar/bar.proto", 1081 Content: ` 1082 syntax = "proto3"; 1083 1084 option go_package = "example.com/repo/foo/bar"; 1085 1086 message Bar {}; 1087 `, 1088 }, 1089 } 1090 dir, cleanup := testtools.CreateFiles(t, files) 1091 defer cleanup() 1092 1093 args := []string{"-go_prefix", "example.com/repo"} 1094 if err := runGazelle(dir, args); err != nil { 1095 t.Fatal(err) 1096 } 1097 1098 testtools.CheckFiles(t, dir, []testtools.FileSpec{ 1099 { 1100 Path: "foo/BUILD.bazel", 1101 Content: ` 1102 load("@io_bazel_rules_go//go:def.bzl", "go_library") 1103 1104 go_library( 1105 name = "go_default_library", 1106 srcs = ["extra.go"], 1107 importpath = "example.com/repo/foo", 1108 visibility = ["//visibility:public"], 1109 ) 1110 `, 1111 }, 1112 }) 1113 } 1114 1115 func TestCustomRepoNamesMain(t *testing.T) { 1116 files := []testtools.FileSpec{ 1117 { 1118 Path: "WORKSPACE", 1119 Content: ` 1120 go_repository( 1121 name = "custom_repo", 1122 importpath = "example.com/bar", 1123 commit = "123456", 1124 ) 1125 `, 1126 }, { 1127 Path: "foo.go", 1128 Content: ` 1129 package foo 1130 1131 import _ "example.com/bar" 1132 `, 1133 }, 1134 } 1135 dir, cleanup := testtools.CreateFiles(t, files) 1136 defer cleanup() 1137 1138 args := []string{"-go_prefix", "example.com/foo"} 1139 if err := runGazelle(dir, args); err != nil { 1140 t.Fatal(err) 1141 } 1142 1143 testtools.CheckFiles(t, dir, []testtools.FileSpec{ 1144 { 1145 Path: "BUILD.bazel", 1146 Content: ` 1147 load("@io_bazel_rules_go//go:def.bzl", "go_library") 1148 1149 go_library( 1150 name = "foo", 1151 srcs = ["foo.go"], 1152 importpath = "example.com/foo", 1153 visibility = ["//visibility:public"], 1154 deps = ["@custom_repo//:bar"], 1155 ) 1156 `, 1157 }, 1158 }) 1159 } 1160 1161 func TestCustomRepoNamesExternal(t *testing.T) { 1162 files := []testtools.FileSpec{ 1163 { 1164 Path: "main/WORKSPACE", 1165 Content: `go_repository( 1166 name = "custom_repo", 1167 importpath = "example.com/bar", 1168 commit = "123456", 1169 ) 1170 `, 1171 }, { 1172 Path: "ext/WORKSPACE", 1173 Content: "", 1174 }, { 1175 Path: "ext/foo.go", 1176 Content: ` 1177 package foo 1178 1179 import _ "example.com/bar" 1180 `, 1181 }, 1182 } 1183 dir, cleanup := testtools.CreateFiles(t, files) 1184 defer cleanup() 1185 1186 extDir := filepath.Join(dir, "ext") 1187 args := []string{ 1188 "-go_prefix=example.com/foo", 1189 "-go_naming_convention=import_alias", 1190 "-mode=fix", 1191 "-repo_root=" + extDir, 1192 "-repo_config=" + filepath.Join(dir, "main", "WORKSPACE"), 1193 } 1194 if err := runGazelle(extDir, args); err != nil { 1195 t.Fatal(err) 1196 } 1197 1198 testtools.CheckFiles(t, dir, []testtools.FileSpec{ 1199 { 1200 Path: "ext/BUILD.bazel", 1201 Content: ` 1202 load("@io_bazel_rules_go//go:def.bzl", "go_library") 1203 1204 go_library( 1205 name = "foo", 1206 srcs = ["foo.go"], 1207 importpath = "example.com/foo", 1208 visibility = ["//visibility:public"], 1209 deps = ["@custom_repo//:bar"], 1210 ) 1211 1212 alias( 1213 name = "go_default_library", 1214 actual = ":foo", 1215 visibility = ["//visibility:public"], 1216 ) 1217 `, 1218 }, 1219 }) 1220 } 1221 1222 func TestUpdateReposWithQueryToWorkspace(t *testing.T) { 1223 files := []testtools.FileSpec{ 1224 { 1225 Path: "WORKSPACE", 1226 Content: ` 1227 load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 1228 1229 http_archive( 1230 name = "io_bazel_rules_go", 1231 sha256 = "8df59f11fb697743cbb3f26cfb8750395f30471e9eabde0d174c3aebc7a1cd39", 1232 urls = [ 1233 "https://storage.googleapis.com/bazel-mirror/github.com/bazelbuild/rules_go/releases/download/0.19.1/rules_go-0.19.1.tar.gz", 1234 "https://github.com/bazelbuild/rules_go/releases/download/0.19.1/rules_go-0.19.1.tar.gz", 1235 ], 1236 ) 1237 1238 http_archive( 1239 name = "bazel_gazelle", 1240 sha256 = "be9296bfd64882e3c08e3283c58fcb461fa6dd3c171764fcc4cf322f60615a9b", 1241 urls = [ 1242 "https://storage.googleapis.com/bazel-mirror/github.com/bazelbuild/bazel-gazelle/releases/download/0.18.1/bazel-gazelle-0.18.1.tar.gz", 1243 "https://github.com/bazelbuild/bazel-gazelle/releases/download/0.18.1/bazel-gazelle-0.18.1.tar.gz", 1244 ], 1245 ) 1246 1247 load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies") 1248 1249 go_rules_dependencies() 1250 1251 go_register_toolchains(nogo = "@bazel_gazelle//:nogo") 1252 1253 load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies") 1254 1255 gazelle_dependencies() 1256 `, 1257 }, 1258 } 1259 1260 dir, cleanup := testtools.CreateFiles(t, files) 1261 defer cleanup() 1262 1263 args := []string{"update-repos", "github.com/sirupsen/logrus@v1.3.0"} 1264 if err := runGazelle(dir, args); err != nil { 1265 t.Fatal(err) 1266 } 1267 1268 testtools.CheckFiles(t, dir, []testtools.FileSpec{ 1269 { 1270 Path: "WORKSPACE", 1271 Content: ` 1272 load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 1273 1274 http_archive( 1275 name = "io_bazel_rules_go", 1276 sha256 = "8df59f11fb697743cbb3f26cfb8750395f30471e9eabde0d174c3aebc7a1cd39", 1277 urls = [ 1278 "https://storage.googleapis.com/bazel-mirror/github.com/bazelbuild/rules_go/releases/download/0.19.1/rules_go-0.19.1.tar.gz", 1279 "https://github.com/bazelbuild/rules_go/releases/download/0.19.1/rules_go-0.19.1.tar.gz", 1280 ], 1281 ) 1282 1283 http_archive( 1284 name = "bazel_gazelle", 1285 sha256 = "be9296bfd64882e3c08e3283c58fcb461fa6dd3c171764fcc4cf322f60615a9b", 1286 urls = [ 1287 "https://storage.googleapis.com/bazel-mirror/github.com/bazelbuild/bazel-gazelle/releases/download/0.18.1/bazel-gazelle-0.18.1.tar.gz", 1288 "https://github.com/bazelbuild/bazel-gazelle/releases/download/0.18.1/bazel-gazelle-0.18.1.tar.gz", 1289 ], 1290 ) 1291 1292 load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies") 1293 1294 go_rules_dependencies() 1295 1296 go_register_toolchains(nogo = "@bazel_gazelle//:nogo") 1297 1298 load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies", "go_repository") 1299 1300 go_repository( 1301 name = "com_github_sirupsen_logrus", 1302 importpath = "github.com/sirupsen/logrus", 1303 sum = "h1:hI/7Q+DtNZ2kINb6qt/lS+IyXnHQe9e90POfeewL/ME=", 1304 version = "v1.3.0", 1305 ) 1306 1307 gazelle_dependencies() 1308 `, 1309 }, 1310 }) 1311 } 1312 1313 func TestDeleteRulesInEmptyDir(t *testing.T) { 1314 files := []testtools.FileSpec{ 1315 {Path: "WORKSPACE"}, 1316 { 1317 Path: "BUILD.bazel", 1318 Content: ` 1319 load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_binary") 1320 1321 go_library( 1322 name = "go_default_library", 1323 srcs = [ 1324 "bar.go", 1325 "foo.go", 1326 ], 1327 importpath = "example.com/repo", 1328 visibility = ["//visibility:private"], 1329 ) 1330 1331 go_binary( 1332 name = "cmd", 1333 embed = [":go_default_library"], 1334 visibility = ["//visibility:public"], 1335 ) 1336 `, 1337 }, 1338 } 1339 dir, cleanup := testtools.CreateFiles(t, files) 1340 defer cleanup() 1341 1342 args := []string{"-go_prefix=example.com/repo"} 1343 if err := runGazelle(dir, args); err != nil { 1344 t.Fatal(err) 1345 } 1346 1347 testtools.CheckFiles(t, dir, []testtools.FileSpec{ 1348 { 1349 Path: "BUILD.bazel", 1350 Content: "", 1351 }, 1352 }) 1353 } 1354 1355 func TestFixWorkspaceWithoutGazelle(t *testing.T) { 1356 files := []testtools.FileSpec{ 1357 { 1358 Path: "WORKSPACE", 1359 Content: ` 1360 load("@io_bazel_rules_go//go:def.bzl", "go_repository") 1361 1362 go_repository( 1363 name = "com_example_repo", 1364 importpath = "example.com/repo", 1365 tag = "1.2.3", 1366 ) 1367 `, 1368 }, 1369 } 1370 dir, cleanup := testtools.CreateFiles(t, files) 1371 defer cleanup() 1372 1373 if err := runGazelle(dir, []string{"fix", "-go_prefix="}); err == nil { 1374 t.Error("got success; want error") 1375 } else if want := "bazel_gazelle is not declared"; !strings.Contains(err.Error(), want) { 1376 t.Errorf("got error %v; want error containing %q", err, want) 1377 } 1378 } 1379 1380 // TestFixGazelle checks that loads of the gazelle macro from the old location 1381 // in rules_go are replaced with the new location in @bazel_gazelle. 1382 func TestFixGazelle(t *testing.T) { 1383 files := []testtools.FileSpec{ 1384 { 1385 Path: "WORKSPACE", 1386 }, { 1387 Path: "BUILD.bazel", 1388 Content: ` 1389 load("@io_bazel_rules_go//go:def.bzl", "gazelle", "go_library") 1390 1391 gazelle(name = "gazelle") 1392 1393 # keep 1394 go_library(name = "go_default_library") 1395 `, 1396 }, 1397 } 1398 dir, cleanup := testtools.CreateFiles(t, files) 1399 defer cleanup() 1400 1401 if err := runGazelle(dir, nil); err != nil { 1402 t.Fatal(err) 1403 } 1404 testtools.CheckFiles(t, dir, []testtools.FileSpec{ 1405 { 1406 Path: "BUILD.bazel", 1407 Content: ` 1408 load("@bazel_gazelle//:def.bzl", "gazelle") 1409 load("@io_bazel_rules_go//go:def.bzl", "go_library") 1410 1411 gazelle(name = "gazelle") 1412 1413 # keep 1414 go_library(name = "go_default_library") 1415 `, 1416 }, 1417 }) 1418 } 1419 1420 // TestKeepDeps checks rules with keep comments on the rule or on the deps 1421 // attribute will not be modified during dependency resolution. Verifies #212. 1422 func TestKeepDeps(t *testing.T) { 1423 files := []testtools.FileSpec{ 1424 { 1425 Path: "WORKSPACE", 1426 }, { 1427 Path: "BUILD.bazel", 1428 Content: ` 1429 load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") 1430 1431 # gazelle:prefix example.com/repo 1432 1433 # keep 1434 go_library( 1435 name = "go_default_library", 1436 srcs = ["lib.go"], 1437 importpath = "example.com/repo", 1438 deps = [":dont_remove"], 1439 ) 1440 1441 go_test( 1442 name = "go_default_test", 1443 # keep 1444 srcs = ["lib_test.go"], 1445 # keep 1446 embed = [":go_default_library"], 1447 # keep 1448 deps = [":dont_remove"], 1449 ) 1450 `, 1451 }, 1452 } 1453 dir, cleanup := testtools.CreateFiles(t, files) 1454 defer cleanup() 1455 1456 if err := runGazelle(dir, nil); err != nil { 1457 t.Fatal(err) 1458 } 1459 1460 testtools.CheckFiles(t, dir, files) 1461 } 1462 1463 func TestDontCreateBuildFileInEmptyDir(t *testing.T) { 1464 files := []testtools.FileSpec{ 1465 {Path: "WORKSPACE"}, 1466 {Path: "sub/"}, 1467 } 1468 dir, cleanup := testtools.CreateFiles(t, files) 1469 defer cleanup() 1470 1471 if err := runGazelle(dir, nil); err != nil { 1472 t.Error(err) 1473 } 1474 for _, f := range []string{"BUILD.bazel", "sub/BUILD.bazel"} { 1475 path := filepath.Join(dir, filepath.FromSlash(f)) 1476 _, err := os.Stat(path) 1477 if err == nil { 1478 t.Errorf("%s: build file was created", f) 1479 } 1480 } 1481 } 1482 1483 // TestNoIndex checks that gazelle does not index existing or generated 1484 // library rules with the flag -index=false. Verifies #384. 1485 func TestNoIndex(t *testing.T) { 1486 files := []testtools.FileSpec{ 1487 {Path: "WORKSPACE"}, 1488 { 1489 Path: "foo/foo.go", 1490 Content: ` 1491 package foo 1492 1493 import _ "example.com/bar" 1494 `, 1495 }, 1496 { 1497 Path: "third_party/example.com/bar/bar.go", 1498 Content: "package bar", 1499 }, 1500 { 1501 Path: "third_party/BUILD.bazel", 1502 Content: "# gazelle:prefix", 1503 }, 1504 { 1505 Path: "third_party/example.com/bar/BUILD.bazel", 1506 Content: ` 1507 load("@io_bazel_rules_go//go:def.bzl", "go_library") 1508 1509 go_library( 1510 name = "bar", 1511 srcs = ["bar.go"], 1512 importpath = "example.com/bar", 1513 visibility = ["//visibility:public"], 1514 ) 1515 `, 1516 }, 1517 } 1518 dir, cleanup := testtools.CreateFiles(t, files) 1519 defer cleanup() 1520 1521 args := []string{ 1522 "-go_prefix=example.com/repo", 1523 "-external=vendored", 1524 "-index=false", 1525 } 1526 if err := runGazelle(dir, args); err != nil { 1527 t.Fatal(err) 1528 } 1529 1530 testtools.CheckFiles(t, dir, []testtools.FileSpec{{ 1531 Path: "foo/BUILD.bazel", 1532 Content: ` 1533 load("@io_bazel_rules_go//go:def.bzl", "go_library") 1534 1535 go_library( 1536 name = "foo", 1537 srcs = ["foo.go"], 1538 importpath = "example.com/repo/foo", 1539 visibility = ["//visibility:public"], 1540 deps = ["//vendor/example.com/bar"], 1541 ) 1542 `, 1543 }}) 1544 } 1545 1546 // TestNoIndexNoRecurse checks that gazelle behaves correctly with the flags 1547 // -r=false -index=false. Gazelle should not generate build files in 1548 // subdirectories and should not resolve dependencies to local libraries. 1549 func TestNoIndexNoRecurse(t *testing.T) { 1550 barBuildFile := testtools.FileSpec{ 1551 Path: "foo/bar/BUILD.bazel", 1552 Content: "# this should not be updated because -r=false", 1553 } 1554 files := []testtools.FileSpec{ 1555 {Path: "WORKSPACE"}, 1556 { 1557 Path: "foo/foo.go", 1558 Content: `package foo 1559 1560 import ( 1561 _ "example.com/dep/baz" 1562 ) 1563 `, 1564 }, 1565 barBuildFile, 1566 { 1567 Path: "foo/bar/bar.go", 1568 Content: "package bar", 1569 }, 1570 { 1571 Path: "third_party/baz/BUILD.bazel", 1572 Content: `load("@io_bazel_rules_go//go:def.bzl", "go_library") 1573 1574 # this should be ignored because -index=false 1575 go_library( 1576 name = "baz", 1577 srcs = ["baz.go"], 1578 importpath = "example.com/dep/baz", 1579 visibility = ["//visibility:public"], 1580 ) 1581 `, 1582 }, 1583 { 1584 Path: "third_party/baz/baz.go", 1585 Content: "package baz", 1586 }, 1587 } 1588 dir, cleanup := testtools.CreateFiles(t, files) 1589 defer cleanup() 1590 1591 args := []string{ 1592 "-go_prefix=example.com/repo", 1593 "-external=vendored", 1594 "-r=false", 1595 "-index=false", 1596 "foo", 1597 } 1598 if err := runGazelle(dir, args); err != nil { 1599 t.Fatal(err) 1600 } 1601 1602 testtools.CheckFiles(t, dir, []testtools.FileSpec{ 1603 { 1604 Path: "foo/BUILD.bazel", 1605 Content: `load("@io_bazel_rules_go//go:def.bzl", "go_library") 1606 1607 go_library( 1608 name = "foo", 1609 srcs = ["foo.go"], 1610 importpath = "example.com/repo/foo", 1611 visibility = ["//visibility:public"], 1612 deps = ["//vendor/example.com/dep/baz"], 1613 ) 1614 `, 1615 }, 1616 barBuildFile, 1617 }) 1618 } 1619 1620 // TestNoIndexRecurse checks that gazelle behaves correctly with the flags 1621 // -r=true -index=false. Gazelle should generate build files in directories 1622 // and subdirectories, but should not resolve dependencies to local libraries. 1623 func TestNoIndexRecurse(t *testing.T) { 1624 files := []testtools.FileSpec{ 1625 {Path: "WORKSPACE"}, { 1626 Path: "foo/foo.go", 1627 Content: `package foo 1628 1629 import ( 1630 _ "example.com/dep/baz" 1631 ) 1632 `, 1633 }, { 1634 Path: "foo/bar/bar.go", 1635 Content: "package bar", 1636 }, { 1637 Path: "third_party/baz/BUILD.bazel", 1638 Content: `load("@io_bazel_rules_go//go:def.bzl", "go_library") 1639 1640 # this should be ignored because -index=false 1641 go_library( 1642 name = "baz", 1643 srcs = ["baz.go"], 1644 importpath = "example.com/dep/baz", 1645 visibility = ["//visibility:public"], 1646 ) 1647 `, 1648 }, { 1649 Path: "third_party/baz/baz.go", 1650 Content: "package baz", 1651 }, 1652 } 1653 dir, cleanup := testtools.CreateFiles(t, files) 1654 defer cleanup() 1655 1656 args := []string{ 1657 "-go_prefix=example.com/repo", 1658 "-external=vendored", 1659 "-r=true", 1660 "-index=false", 1661 "foo", 1662 } 1663 if err := runGazelle(dir, args); err != nil { 1664 t.Fatal(err) 1665 } 1666 1667 testtools.CheckFiles(t, dir, []testtools.FileSpec{ 1668 { 1669 Path: "foo/BUILD.bazel", 1670 Content: `load("@io_bazel_rules_go//go:def.bzl", "go_library") 1671 1672 go_library( 1673 name = "foo", 1674 srcs = ["foo.go"], 1675 importpath = "example.com/repo/foo", 1676 visibility = ["//visibility:public"], 1677 deps = ["//vendor/example.com/dep/baz"], 1678 ) 1679 `, 1680 }, { 1681 Path: "foo/bar/BUILD.bazel", 1682 Content: `load("@io_bazel_rules_go//go:def.bzl", "go_library") 1683 1684 go_library( 1685 name = "bar", 1686 srcs = ["bar.go"], 1687 importpath = "example.com/repo/foo/bar", 1688 visibility = ["//visibility:public"], 1689 ) 1690 `, 1691 }, 1692 }) 1693 } 1694 1695 // TestSubdirectoryPrefixExternal checks that directives set in subdirectories 1696 // may be used in dependency resolution. Verifies #412. 1697 func TestSubdirectoryPrefixExternal(t *testing.T) { 1698 files := []testtools.FileSpec{ 1699 { 1700 Path: "WORKSPACE", 1701 }, { 1702 Path: "BUILD.bazel", 1703 Content: "# gazelle:prefix", 1704 }, { 1705 Path: "sub/BUILD.bazel", 1706 Content: "# gazelle:prefix example.com/sub", 1707 }, { 1708 Path: "sub/sub.go", 1709 Content: ` 1710 package sub 1711 1712 import ( 1713 _ "example.com/sub/missing" 1714 _ "example.com/external" 1715 ) 1716 `, 1717 }, 1718 } 1719 dir, cleanup := testtools.CreateFiles(t, files) 1720 defer cleanup() 1721 1722 if err := runGazelle(dir, []string{"-external=vendored", "-index=false"}); err != nil { 1723 t.Fatal(err) 1724 } 1725 1726 testtools.CheckFiles(t, dir, []testtools.FileSpec{ 1727 { 1728 Path: "sub/BUILD.bazel", 1729 Content: ` 1730 load("@io_bazel_rules_go//go:def.bzl", "go_library") 1731 1732 # gazelle:prefix example.com/sub 1733 1734 go_library( 1735 name = "sub", 1736 srcs = ["sub.go"], 1737 importpath = "example.com/sub", 1738 visibility = ["//visibility:public"], 1739 deps = [ 1740 "//sub/missing", 1741 "//vendor/example.com/external", 1742 ], 1743 ) 1744 `, 1745 }, 1746 }) 1747 } 1748 1749 func TestGoGrpcProtoFlag(t *testing.T) { 1750 files := []testtools.FileSpec{ 1751 { 1752 Path: "WORKSPACE", 1753 }, { 1754 Path: "BUILD.bazel", 1755 Content: ` 1756 load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") 1757 load("@io_bazel_rules_go//go:def.bzl", "go_library") 1758 load("@rules_proto//proto:defs.bzl", "proto_library") 1759 1760 go_proto_library( 1761 name = "foo_go_proto", 1762 importpath = "example.com/repo/foo", 1763 proto = ":foo_proto", 1764 visibility = ["//visibility:public"], 1765 ) 1766 1767 proto_library( 1768 name = "foo_proto", 1769 srcs = ["foo.proto"], 1770 visibility = ["//visibility:public"], 1771 ) 1772 1773 go_library( 1774 name = "go_default_library", 1775 embed = [":foo_go_proto"], 1776 importpath = "example.com/repo/foo", 1777 visibility = ["//visibility:public"], 1778 ) 1779 `, 1780 }, { 1781 Path: "foo.proto", 1782 Content: ` 1783 syntax = "proto3"; 1784 1785 option go_package = "example.com/repo/foo"; 1786 1787 message Bar {}; 1788 `, 1789 }, { 1790 Path: "service/BUILD.bazel", 1791 Content: ` 1792 load("@rules_proto//proto:defs.bzl", "proto_library") 1793 load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") 1794 load("@io_bazel_rules_go//go:def.bzl", "go_library") 1795 1796 go_proto_library( 1797 name = "service_go_proto", 1798 compilers = ["@io_bazel_rules_go//proto:go_grpc"], 1799 importpath = "example.com/repo/service", 1800 proto = ":service_proto", 1801 visibility = ["//visibility:public"], 1802 ) 1803 1804 proto_library( 1805 name = "service_proto", 1806 srcs = ["service.proto"], 1807 visibility = ["//visibility:public"], 1808 ) 1809 1810 go_library( 1811 name = "go_default_library", 1812 embed = [":service_go_proto"], 1813 importpath = "example.com/repo/service", 1814 visibility = ["//visibility:public"], 1815 ) 1816 `, 1817 }, { 1818 Path: "service/service.proto", 1819 Content: ` 1820 syntax = "proto3"; 1821 1822 option go_package = "example.com/repo/service"; 1823 1824 service TestService {} 1825 `, 1826 }, 1827 } 1828 dir, cleanup := testtools.CreateFiles(t, files) 1829 defer cleanup() 1830 1831 args := []string{"update", "-go_grpc_compiler", "//foo", "-go_proto_compiler", "//bar"} 1832 if err := runGazelle(dir, args); err != nil { 1833 t.Fatal(err) 1834 } 1835 1836 testtools.CheckFiles(t, dir, []testtools.FileSpec{ 1837 { 1838 Path: "BUILD.bazel", 1839 Content: ` 1840 load("@io_bazel_rules_go//go:def.bzl", "go_library") 1841 load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") 1842 load("@rules_proto//proto:defs.bzl", "proto_library") 1843 1844 go_proto_library( 1845 name = "foo_go_proto", 1846 compilers = ["//bar"], 1847 importpath = "example.com/repo/foo", 1848 proto = ":foo_proto", 1849 visibility = ["//visibility:public"], 1850 ) 1851 1852 proto_library( 1853 name = "foo_proto", 1854 srcs = ["foo.proto"], 1855 visibility = ["//visibility:public"], 1856 ) 1857 1858 go_library( 1859 name = "go_default_library", 1860 embed = [":foo_go_proto"], 1861 importpath = "example.com/repo/foo", 1862 visibility = ["//visibility:public"], 1863 ) 1864 `, 1865 }, 1866 { 1867 Path: "service/BUILD.bazel", 1868 Content: ` 1869 load("@io_bazel_rules_go//go:def.bzl", "go_library") 1870 load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") 1871 load("@rules_proto//proto:defs.bzl", "proto_library") 1872 1873 go_proto_library( 1874 name = "service_go_proto", 1875 compilers = ["//foo"], 1876 importpath = "example.com/repo/service", 1877 proto = ":service_proto", 1878 visibility = ["//visibility:public"], 1879 ) 1880 1881 proto_library( 1882 name = "service_proto", 1883 srcs = ["service.proto"], 1884 visibility = ["//visibility:public"], 1885 ) 1886 1887 go_library( 1888 name = "go_default_library", 1889 embed = [":service_go_proto"], 1890 importpath = "example.com/repo/service", 1891 visibility = ["//visibility:public"], 1892 ) 1893 `, 1894 }, 1895 }) 1896 } 1897 1898 // TestMapKind tests the gazelle:map_kind directive. 1899 // Verifies #448 1900 func TestMapKind(t *testing.T) { 1901 files := []testtools.FileSpec{ 1902 { 1903 Path: "WORKSPACE", 1904 }, 1905 { 1906 Path: "BUILD.bazel", 1907 Content: ` 1908 # gazelle:prefix example.com/mapkind 1909 # gazelle:go_naming_convention go_default_library 1910 `, 1911 }, 1912 { 1913 Path: "root_lib.go", 1914 Content: `package mapkind`, 1915 }, 1916 { 1917 Path: "enabled/BUILD.bazel", 1918 Content: "# gazelle:map_kind go_library my_library //tools/go:def.bzl", 1919 }, 1920 { 1921 Path: "enabled/enabled_lib.go", 1922 Content: `package enabled`, 1923 }, 1924 { 1925 Path: "enabled/inherited/BUILD.bazel", 1926 }, 1927 { 1928 Path: "enabled/inherited/inherited_lib.go", 1929 Content: `package inherited`, 1930 }, 1931 { 1932 Path: "enabled/existing_rules/mapped/BUILD.bazel", 1933 Content: ` 1934 load("//tools/go:def.bzl", "my_library") 1935 1936 # An existing rule with a mapped type is updated 1937 my_library( 1938 name = "go_default_library", 1939 srcs = ["deleted_file.go", "mapped_lib.go"], 1940 importpath = "example.com/mapkind/enabled/existing_rules/mapped", 1941 visibility = ["//visibility:public"], 1942 ) 1943 `, 1944 }, 1945 { 1946 Path: "enabled/existing_rules/mapped/mapped_lib.go", 1947 Content: `package mapped`, 1948 }, 1949 { 1950 Path: "enabled/existing_rules/mapped/mapped_lib2.go", 1951 Content: `package mapped`, 1952 }, 1953 { 1954 Path: "enabled/existing_rules/unmapped/BUILD.bazel", 1955 Content: ` 1956 load("@io_bazel_rules_go//go:def.bzl", "go_library") 1957 1958 # An existing rule with an unmapped type is updated 1959 go_library( 1960 name = "go_default_library", 1961 srcs = ["unmapped_lib.go"], 1962 importpath = "example.com/mapkind/enabled/existing_rules/unmapped", 1963 visibility = ["//visibility:public"], 1964 ) 1965 `, 1966 }, 1967 { 1968 Path: "enabled/existing_rules/unmapped/unmapped_lib.go", 1969 Content: `package unmapped`, 1970 }, 1971 { 1972 Path: "enabled/existing_rules/clean/BUILD.bazel", 1973 Content: `load("//tools/go:def.bzl", "my_go_library") 1974 1975 # gazelle:go_naming_convention import 1976 # gazelle:map_kind go_library my_go_library //tools/go:def.bzl 1977 1978 my_go_library( 1979 name = "clean", 1980 srcs = [ 1981 "foo.go", 1982 "bar.go", 1983 "buz.go", 1984 ], 1985 importpath = "example.com/mapkind/enabled/existing_rules/clean", 1986 visibility = ["//visibility:private"], 1987 ) 1988 `, 1989 }, 1990 { 1991 Path: "enabled/existing_rules/clean_binary/BUILD.bazel", 1992 Content: `load("//tools/go:def.bzl", "my_go_binary", "my_go_library") 1993 1994 # gazelle:go_naming_convention import 1995 # gazelle:map_kind go_binary my_go_binary //tools/go:def.bzl 1996 # gazelle:map_kind go_library my_go_library //tools/go:def.bzl 1997 1998 my_go_library( 1999 name = "clean_binary_lib", 2000 srcs = ["main.go"], 2001 importpath = "example.com/mapkind/enabled/existing_rules/clean_binary", 2002 visibility = ["//visibility:private"], 2003 ) 2004 2005 my_go_binary( 2006 name = "clean_binary", 2007 embed = [":clean_binary_lib"], 2008 visibility = ["//visibility:public"], 2009 ) 2010 `, 2011 }, 2012 { 2013 Path: "enabled/existing_rules/nobuild/nobuild_lib.go", 2014 Content: `package nobuild`, 2015 }, 2016 { 2017 Path: "enabled/overridden/BUILD.bazel", 2018 Content: "# gazelle:map_kind go_library overridden_library //tools/overridden:def.bzl", 2019 }, 2020 { 2021 Path: "enabled/overridden/overridden_lib.go", 2022 Content: `package overridden`, 2023 }, 2024 { 2025 Path: "disabled/BUILD.bazel", 2026 }, 2027 { 2028 Path: "disabled/disabled_lib.go", 2029 Content: `package disabled`, 2030 }, 2031 { 2032 Path: "enabled/multiple_mappings/BUILD.bazel", 2033 Content: ` 2034 # gazelle:map_kind go_binary go_binary //tools/go:def.bzl 2035 # gazelle:map_kind go_library go_library //tools/go:def.bzl 2036 `, 2037 }, 2038 { 2039 Path: "enabled/multiple_mappings/multiple_mappings.go", 2040 Content: ` 2041 package main 2042 2043 func main() {}`, 2044 }, 2045 { 2046 Path: "depend_on_mapped_kind/lib.go", 2047 Content: `package depend_on_mapped_kind 2048 import ( 2049 _ "example.com/mapkind/disabled" 2050 _ "example.com/mapkind/enabled" 2051 _ "example.com/mapkind/enabled/existing_rules/mapped" 2052 _ "example.com/mapkind/enabled/existing_rules/unmapped" 2053 _ "example.com/mapkind/enabled/overridden" 2054 )`, 2055 }, 2056 } 2057 dir, cleanup := testtools.CreateFiles(t, files) 2058 defer cleanup() 2059 2060 if err := runGazelle(dir, []string{"-external=vendored"}); err != nil { 2061 t.Fatal(err) 2062 } 2063 2064 testtools.CheckFiles(t, dir, []testtools.FileSpec{ 2065 { 2066 Path: "BUILD.bazel", 2067 Content: ` 2068 load("@io_bazel_rules_go//go:def.bzl", "go_library") 2069 2070 # gazelle:prefix example.com/mapkind 2071 # gazelle:go_naming_convention go_default_library 2072 2073 go_library( 2074 name = "go_default_library", 2075 srcs = ["root_lib.go"], 2076 importpath = "example.com/mapkind", 2077 visibility = ["//visibility:public"], 2078 ) 2079 `, 2080 }, 2081 { 2082 Path: "enabled/BUILD.bazel", 2083 Content: ` 2084 load("//tools/go:def.bzl", "my_library") 2085 2086 # gazelle:map_kind go_library my_library //tools/go:def.bzl 2087 2088 my_library( 2089 name = "go_default_library", 2090 srcs = ["enabled_lib.go"], 2091 importpath = "example.com/mapkind/enabled", 2092 visibility = ["//visibility:public"], 2093 ) 2094 `, 2095 }, 2096 { 2097 Path: "enabled/inherited/BUILD.bazel", 2098 Content: ` 2099 load("//tools/go:def.bzl", "my_library") 2100 2101 my_library( 2102 name = "go_default_library", 2103 srcs = ["inherited_lib.go"], 2104 importpath = "example.com/mapkind/enabled/inherited", 2105 visibility = ["//visibility:public"], 2106 ) 2107 `, 2108 }, 2109 { 2110 Path: "enabled/overridden/BUILD.bazel", 2111 Content: ` 2112 load("//tools/overridden:def.bzl", "overridden_library") 2113 2114 # gazelle:map_kind go_library overridden_library //tools/overridden:def.bzl 2115 2116 overridden_library( 2117 name = "go_default_library", 2118 srcs = ["overridden_lib.go"], 2119 importpath = "example.com/mapkind/enabled/overridden", 2120 visibility = ["//visibility:public"], 2121 ) 2122 `, 2123 }, 2124 { 2125 Path: "disabled/BUILD.bazel", 2126 Content: ` 2127 load("@io_bazel_rules_go//go:def.bzl", "go_library") 2128 2129 go_library( 2130 name = "go_default_library", 2131 srcs = ["disabled_lib.go"], 2132 importpath = "example.com/mapkind/disabled", 2133 visibility = ["//visibility:public"], 2134 ) 2135 `, 2136 }, 2137 { 2138 Path: "enabled/existing_rules/mapped/BUILD.bazel", 2139 Content: ` 2140 load("//tools/go:def.bzl", "my_library") 2141 2142 # An existing rule with a mapped type is updated 2143 my_library( 2144 name = "go_default_library", 2145 srcs = [ 2146 "mapped_lib.go", 2147 "mapped_lib2.go", 2148 ], 2149 importpath = "example.com/mapkind/enabled/existing_rules/mapped", 2150 visibility = ["//visibility:public"], 2151 ) 2152 `, 2153 }, 2154 { 2155 Path: "enabled/existing_rules/unmapped/BUILD.bazel", 2156 Content: ` 2157 load("//tools/go:def.bzl", "my_library") 2158 2159 # An existing rule with an unmapped type is updated 2160 my_library( 2161 name = "go_default_library", 2162 srcs = ["unmapped_lib.go"], 2163 importpath = "example.com/mapkind/enabled/existing_rules/unmapped", 2164 visibility = ["//visibility:public"], 2165 ) 2166 `, 2167 }, 2168 { 2169 Path: "enabled/existing_rules/clean/BUILD.bazel", 2170 Content: ` 2171 # gazelle:go_naming_convention import 2172 # gazelle:map_kind go_library my_go_library //tools/go:def.bzl 2173 `, 2174 }, 2175 { 2176 Path: "enabled/existing_rules/clean_binary/BUILD.bazel", 2177 Content: ` 2178 # gazelle:go_naming_convention import 2179 # gazelle:map_kind go_binary my_go_binary //tools/go:def.bzl 2180 # gazelle:map_kind go_library my_go_library //tools/go:def.bzl 2181 `, 2182 }, 2183 { 2184 Path: "enabled/existing_rules/nobuild/BUILD.bazel", 2185 Content: ` 2186 load("//tools/go:def.bzl", "my_library") 2187 2188 my_library( 2189 name = "go_default_library", 2190 srcs = ["nobuild_lib.go"], 2191 importpath = "example.com/mapkind/enabled/existing_rules/nobuild", 2192 visibility = ["//visibility:public"], 2193 ) 2194 `, 2195 }, 2196 { 2197 Path: "enabled/multiple_mappings/BUILD.bazel", 2198 Content: ` 2199 load("//tools/go:def.bzl", "go_binary", "go_library") 2200 2201 # gazelle:map_kind go_binary go_binary //tools/go:def.bzl 2202 # gazelle:map_kind go_library go_library //tools/go:def.bzl 2203 2204 go_library( 2205 name = "go_default_library", 2206 srcs = ["multiple_mappings.go"], 2207 importpath = "example.com/mapkind/enabled/multiple_mappings", 2208 visibility = ["//visibility:private"], 2209 ) 2210 2211 go_binary( 2212 name = "multiple_mappings", 2213 embed = [":go_default_library"], 2214 visibility = ["//visibility:public"], 2215 ) 2216 `, 2217 }, 2218 { 2219 Path: "depend_on_mapped_kind/BUILD.bazel", 2220 Content: ` 2221 load("@io_bazel_rules_go//go:def.bzl", "go_library") 2222 2223 go_library( 2224 name = "go_default_library", 2225 srcs = ["lib.go"], 2226 importpath = "example.com/mapkind/depend_on_mapped_kind", 2227 visibility = ["//visibility:public"], 2228 deps = [ 2229 "//disabled:go_default_library", 2230 "//enabled:go_default_library", 2231 "//enabled/existing_rules/mapped:go_default_library", 2232 "//enabled/existing_rules/unmapped:go_default_library", 2233 "//enabled/overridden:go_default_library", 2234 ], 2235 ) 2236 `, 2237 }, 2238 }) 2239 } 2240 2241 func TestMapKindEdgeCases(t *testing.T) { 2242 for name, tc := range map[string]struct { 2243 before []testtools.FileSpec 2244 after []testtools.FileSpec 2245 }{ 2246 "new generated rule applies map_kind": { 2247 before: []testtools.FileSpec{ 2248 { 2249 Path: "WORKSPACE", 2250 }, 2251 { 2252 Path: "BUILD.bazel", 2253 Content: `# gazelle:prefix example.com/mapkind 2254 # gazelle:go_naming_convention go_default_library 2255 # gazelle:map_kind go_library go_library //custom:def.bzl 2256 `, 2257 }, 2258 { 2259 Path: "dir/file.go", 2260 Content: "package dir", 2261 }, 2262 }, 2263 after: []testtools.FileSpec{ 2264 { 2265 Path: "dir/BUILD.bazel", 2266 Content: `load("//custom:def.bzl", "go_library") 2267 2268 go_library( 2269 name = "go_default_library", 2270 srcs = ["file.go"], 2271 importpath = "example.com/mapkind/dir", 2272 visibility = ["//visibility:public"], 2273 ) 2274 `, 2275 }, 2276 }, 2277 }, 2278 "existing generated rule with non-renaming mapping applied applies map_kind": { 2279 before: []testtools.FileSpec{ 2280 { 2281 Path: "WORKSPACE", 2282 }, 2283 { 2284 Path: "BUILD.bazel", 2285 Content: `# gazelle:prefix example.com/mapkind 2286 # gazelle:go_naming_convention go_default_library 2287 # gazelle:map_kind go_library go_library //custom:def.bzl 2288 `, 2289 }, 2290 { 2291 Path: "dir/BUILD.bazel", 2292 Content: `load("//custom:def.bzl", "go_library") 2293 2294 go_library( 2295 name = "go_default_library", 2296 srcs = ["file.go"], 2297 importpath = "example.com/mapkind/dir", 2298 visibility = ["//visibility:public"], 2299 ) 2300 `, 2301 }, 2302 { 2303 Path: "dir/file.go", 2304 Content: "package dir", 2305 }, 2306 }, 2307 after: []testtools.FileSpec{ 2308 { 2309 Path: "dir/BUILD.bazel", 2310 Content: `load("//custom:def.bzl", "go_library") 2311 2312 go_library( 2313 name = "go_default_library", 2314 srcs = ["file.go"], 2315 importpath = "example.com/mapkind/dir", 2316 visibility = ["//visibility:public"], 2317 ) 2318 `, 2319 }, 2320 }, 2321 }, 2322 "existing generated rule without non-renaming mapping applied applies map_kind": { 2323 before: []testtools.FileSpec{ 2324 { 2325 Path: "WORKSPACE", 2326 }, 2327 { 2328 Path: "BUILD.bazel", 2329 Content: `# gazelle:prefix example.com/mapkind 2330 # gazelle:go_naming_convention go_default_library 2331 # gazelle:map_kind go_library go_library //custom:def.bzl 2332 `, 2333 }, 2334 { 2335 Path: "dir/BUILD.bazel", 2336 Content: `load("@io_bazel_rules_go//go:def.bzl", "go_library") 2337 2338 go_library( 2339 name = "go_default_library", 2340 srcs = ["file.go"], 2341 importpath = "example.com/mapkind/dir", 2342 visibility = ["//visibility:public"], 2343 ) 2344 `, 2345 }, 2346 { 2347 Path: "dir/file.go", 2348 Content: "package dir", 2349 }, 2350 }, 2351 after: []testtools.FileSpec{ 2352 { 2353 Path: "dir/BUILD.bazel", 2354 Content: `load("//custom:def.bzl", "go_library") 2355 2356 go_library( 2357 name = "go_default_library", 2358 srcs = ["file.go"], 2359 importpath = "example.com/mapkind/dir", 2360 visibility = ["//visibility:public"], 2361 ) 2362 `, 2363 }, 2364 }, 2365 }, 2366 "existing generated rule without renaming mapping applied applies map_kind": { 2367 before: []testtools.FileSpec{ 2368 { 2369 Path: "WORKSPACE", 2370 }, 2371 { 2372 Path: "BUILD.bazel", 2373 Content: `# gazelle:prefix example.com/mapkind 2374 # gazelle:go_naming_convention go_default_library 2375 # gazelle:map_kind go_library custom_go_library //custom:def.bzl 2376 `, 2377 }, 2378 { 2379 Path: "dir/BUILD.bazel", 2380 Content: `load("@io_bazel_rules_go//go:def.bzl", "go_library") 2381 2382 go_library( 2383 name = "go_default_library", 2384 srcs = ["file.go"], 2385 importpath = "example.com/mapkind/dir", 2386 visibility = ["//visibility:public"], 2387 ) 2388 `, 2389 }, 2390 { 2391 Path: "dir/file.go", 2392 Content: "package dir", 2393 }, 2394 }, 2395 after: []testtools.FileSpec{ 2396 { 2397 Path: "dir/BUILD.bazel", 2398 Content: `load("//custom:def.bzl", "custom_go_library") 2399 2400 custom_go_library( 2401 name = "go_default_library", 2402 srcs = ["file.go"], 2403 importpath = "example.com/mapkind/dir", 2404 visibility = ["//visibility:public"], 2405 ) 2406 `, 2407 }, 2408 }, 2409 }, 2410 "existing generated rule with renaming mapping applied preserves map_kind": { 2411 before: []testtools.FileSpec{ 2412 { 2413 Path: "WORKSPACE", 2414 }, 2415 { 2416 Path: "BUILD.bazel", 2417 Content: `# gazelle:prefix example.com/mapkind 2418 # gazelle:go_naming_convention go_default_library 2419 # gazelle:map_kind go_library custom_go_library //custom:def.bzl 2420 `, 2421 }, 2422 { 2423 Path: "dir/BUILD.bazel", 2424 Content: `load("//custom:def.bzl", "custom_go_library") 2425 2426 custom_go_library( 2427 name = "go_default_library", 2428 srcs = ["file.go"], 2429 importpath = "example.com/mapkind/dir", 2430 visibility = ["//visibility:public"], 2431 ) 2432 `, 2433 }, 2434 { 2435 Path: "dir/file.go", 2436 Content: "package dir", 2437 }, 2438 }, 2439 after: []testtools.FileSpec{ 2440 { 2441 Path: "dir/BUILD.bazel", 2442 Content: `load("//custom:def.bzl", "custom_go_library") 2443 2444 custom_go_library( 2445 name = "go_default_library", 2446 srcs = ["file.go"], 2447 importpath = "example.com/mapkind/dir", 2448 visibility = ["//visibility:public"], 2449 ) 2450 `, 2451 }, 2452 }, 2453 }, 2454 "unrelated non-generated non-map_kind'd rule of same kind applies map_kind if other rule is generated": { 2455 before: []testtools.FileSpec{ 2456 { 2457 Path: "WORKSPACE", 2458 }, 2459 { 2460 Path: "BUILD.bazel", 2461 Content: `# gazelle:prefix example.com/mapkind 2462 # gazelle:go_naming_convention go_default_library 2463 # gazelle:map_kind go_library go_library //custom:def.bzl 2464 `, 2465 }, 2466 { 2467 Path: "dir/file.go", 2468 Content: "package dir", 2469 }, 2470 { 2471 Path: "dir/BUILD.bazel", 2472 Content: `load("@io_bazel_rules_go//go:def.bzl", "go_library") 2473 2474 go_library( 2475 name = "custom_lib", 2476 srcs = ["custom_lib.go"], 2477 ) 2478 `, 2479 }, 2480 }, 2481 after: []testtools.FileSpec{ 2482 { 2483 Path: "dir/BUILD.bazel", 2484 Content: `load("//custom:def.bzl", "go_library") 2485 2486 go_library( 2487 name = "custom_lib", 2488 srcs = ["custom_lib.go"], 2489 ) 2490 2491 go_library( 2492 name = "go_default_library", 2493 srcs = ["file.go"], 2494 importpath = "example.com/mapkind/dir", 2495 visibility = ["//visibility:public"], 2496 ) 2497 `, 2498 }, 2499 }, 2500 }, 2501 "unrelated non-generated non-renaming map_kind'd rule of same kind keeps map_kind if other rule is generated": { 2502 before: []testtools.FileSpec{ 2503 { 2504 Path: "WORKSPACE", 2505 }, 2506 { 2507 Path: "BUILD.bazel", 2508 Content: `# gazelle:prefix example.com/mapkind 2509 # gazelle:go_naming_convention go_default_library 2510 # gazelle:map_kind go_library go_library //custom:def.bzl 2511 `, 2512 }, 2513 { 2514 Path: "dir/file.go", 2515 Content: "package dir", 2516 }, 2517 { 2518 Path: "dir/BUILD.bazel", 2519 Content: `load("//custom:def.bzl", "go_library") 2520 2521 go_library( 2522 name = "custom_lib", 2523 srcs = ["custom_lib.go"], 2524 ) 2525 `, 2526 }, 2527 }, 2528 after: []testtools.FileSpec{ 2529 { 2530 Path: "dir/BUILD.bazel", 2531 Content: `load("//custom:def.bzl", "go_library") 2532 2533 go_library( 2534 name = "custom_lib", 2535 srcs = ["custom_lib.go"], 2536 ) 2537 2538 go_library( 2539 name = "go_default_library", 2540 srcs = ["file.go"], 2541 importpath = "example.com/mapkind/dir", 2542 visibility = ["//visibility:public"], 2543 ) 2544 `, 2545 }, 2546 }, 2547 }, 2548 "unrelated non-generated non-renaming map_kind'd rule keeps map_kind if other generated rule is newly generated": { 2549 before: []testtools.FileSpec{ 2550 { 2551 Path: "WORKSPACE", 2552 }, 2553 { 2554 Path: "BUILD.bazel", 2555 Content: `# gazelle:prefix example.com/mapkind 2556 # gazelle:go_naming_convention go_default_library 2557 # gazelle:map_kind go_library go_library //custom:def.bzl 2558 # gazelle:map_kind go_test go_test //custom:def.bzl 2559 `, 2560 }, 2561 { 2562 Path: "dir/file.go", 2563 Content: "package dir", 2564 }, 2565 { 2566 Path: "dir/BUILD.bazel", 2567 Content: `load("//custom:def.bzl", "go_test") 2568 2569 go_test( 2570 name = "custom_test", 2571 srcs = ["custom_test.java"], 2572 ) 2573 `, 2574 }, 2575 }, 2576 after: []testtools.FileSpec{ 2577 { 2578 Path: "dir/BUILD.bazel", 2579 Content: `load("//custom:def.bzl", "go_library", "go_test") 2580 2581 go_test( 2582 name = "custom_test", 2583 srcs = ["custom_test.java"], 2584 ) 2585 2586 go_library( 2587 name = "go_default_library", 2588 srcs = ["file.go"], 2589 importpath = "example.com/mapkind/dir", 2590 visibility = ["//visibility:public"], 2591 ) 2592 `, 2593 }, 2594 }, 2595 }, 2596 "unrelated non-generated non-renaming map_kind'd rule keeps map_kind if other generated rule already existed": { 2597 before: []testtools.FileSpec{ 2598 { 2599 Path: "WORKSPACE", 2600 }, 2601 { 2602 Path: "BUILD.bazel", 2603 Content: `# gazelle:prefix example.com/mapkind 2604 # gazelle:go_naming_convention go_default_library 2605 # gazelle:map_kind go_library go_library //custom:def.bzl 2606 # gazelle:map_kind go_test go_test //custom:def.bzl 2607 `, 2608 }, 2609 { 2610 Path: "dir/file.go", 2611 Content: "package dir", 2612 }, 2613 { 2614 Path: "dir/BUILD.bazel", 2615 Content: `load("//custom:def.bzl", "go_library", "go_test") 2616 2617 go_test( 2618 name = "custom_test", 2619 srcs = ["custom_test.java"], 2620 ) 2621 2622 go_library( 2623 name = "go_default_library", 2624 srcs = ["file.go"], 2625 importpath = "example.com/mapkind/dir", 2626 visibility = ["//visibility:public"], 2627 ) 2628 `, 2629 }, 2630 }, 2631 after: []testtools.FileSpec{ 2632 { 2633 Path: "dir/BUILD.bazel", 2634 Content: `load("//custom:def.bzl", "go_library", "go_test") 2635 2636 go_test( 2637 name = "custom_test", 2638 srcs = ["custom_test.java"], 2639 ) 2640 2641 go_library( 2642 name = "go_default_library", 2643 srcs = ["file.go"], 2644 importpath = "example.com/mapkind/dir", 2645 visibility = ["//visibility:public"], 2646 ) 2647 `, 2648 }, 2649 }, 2650 }, 2651 "transitive remappings are applied": { 2652 before: []testtools.FileSpec{ 2653 { 2654 Path: "WORKSPACE", 2655 }, 2656 { 2657 Path: "BUILD.bazel", 2658 Content: `# gazelle:prefix example.com/mapkind 2659 # gazelle:go_naming_convention go_default_library 2660 # gazelle:map_kind go_library custom_go_library //custom:def.bzl 2661 `, 2662 }, 2663 { 2664 Path: "dir/file.go", 2665 Content: "package dir", 2666 }, 2667 { 2668 Path: "dir/BUILD.bazel", 2669 Content: `# gazelle:map_kind custom_go_library other_custom_go_library //another/custom:def.bzl 2670 `, 2671 }, 2672 }, 2673 after: []testtools.FileSpec{ 2674 { 2675 Path: "dir/BUILD.bazel", 2676 Content: `load("//another/custom:def.bzl", "other_custom_go_library") 2677 2678 # gazelle:map_kind custom_go_library other_custom_go_library //another/custom:def.bzl 2679 2680 other_custom_go_library( 2681 name = "go_default_library", 2682 srcs = ["file.go"], 2683 importpath = "example.com/mapkind/dir", 2684 visibility = ["//visibility:public"], 2685 ) 2686 `, 2687 }, 2688 }, 2689 }, 2690 } { 2691 t.Run(name, func(t *testing.T) { 2692 dir, cleanup := testtools.CreateFiles(t, tc.before) 2693 t.Cleanup(cleanup) 2694 if err := runGazelle(dir, []string{"-external=vendored"}); err != nil { 2695 t.Fatal(err) 2696 } 2697 testtools.CheckFiles(t, dir, tc.after) 2698 }) 2699 } 2700 } 2701 2702 func TestMapKindLoop(t *testing.T) { 2703 dir, cleanup := testtools.CreateFiles(t, []testtools.FileSpec{ 2704 { 2705 Path: "WORKSPACE", 2706 }, 2707 { 2708 Path: "BUILD.bazel", 2709 Content: `# gazelle:prefix example.com/mapkind 2710 # gazelle:go_naming_convention go_default_library 2711 # gazelle:map_kind go_library custom_go_library //custom:def.bzl 2712 `, 2713 }, 2714 { 2715 Path: "dir/file.go", 2716 Content: "package dir", 2717 }, 2718 { 2719 Path: "dir/BUILD.bazel", 2720 Content: `# gazelle:map_kind custom_go_library go_library @io_bazel_rules_go//go:def.bzl 2721 `, 2722 }, 2723 }) 2724 t.Cleanup(cleanup) 2725 err := runGazelle(dir, []string{"-external=vendored"}) 2726 if err == nil { 2727 t.Fatal("Expected error running gazelle with map_kind loop") 2728 } 2729 msg := err.Error() 2730 if !strings.Contains(msg, "looking up mapped kind: found loop of map_kind replacements: go_library -> custom_go_library -> go_library") { 2731 t.Fatalf("Expected error to contain useful descriptors but was %q", msg) 2732 } 2733 } 2734 2735 // TestMapKindEmbeddedResolve tests the gazelle:map_kind properly resolves 2736 // dependencies for embedded rules (see #1162). 2737 func TestMapKindEmbeddedResolve(t *testing.T) { 2738 files := []testtools.FileSpec{ 2739 { 2740 Path: "WORKSPACE", 2741 }, { 2742 Path: "BUILD.bazel", 2743 Content: ` 2744 # gazelle:prefix example.com/mapkind 2745 # gazelle:map_kind go_library my_go_library //:my.bzl 2746 `, 2747 }, { 2748 Path: "a/a.proto", 2749 Content: ` 2750 syntax = "proto3"; 2751 2752 package test; 2753 option go_package = "example.com/mapkind/a"; 2754 `, 2755 }, { 2756 Path: "b/b.proto", 2757 Content: ` 2758 syntax = "proto3"; 2759 2760 package test; 2761 option go_package = "example.com/mapkind/b"; 2762 2763 import "a/a.proto"; 2764 `, 2765 }, 2766 } 2767 dir, cleanup := testtools.CreateFiles(t, files) 2768 defer cleanup() 2769 2770 if err := runGazelle(dir, []string{"-external=vendored"}); err != nil { 2771 t.Fatal(err) 2772 } 2773 2774 testtools.CheckFiles(t, dir, []testtools.FileSpec{ 2775 { 2776 Path: "a/BUILD.bazel", 2777 Content: ` 2778 load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") 2779 load("@rules_proto//proto:defs.bzl", "proto_library") 2780 load("//:my.bzl", "my_go_library") 2781 2782 proto_library( 2783 name = "a_proto", 2784 srcs = ["a.proto"], 2785 visibility = ["//visibility:public"], 2786 ) 2787 2788 go_proto_library( 2789 name = "a_go_proto", 2790 importpath = "example.com/mapkind/a", 2791 proto = ":a_proto", 2792 visibility = ["//visibility:public"], 2793 ) 2794 2795 my_go_library( 2796 name = "a", 2797 embed = [":a_go_proto"], 2798 importpath = "example.com/mapkind/a", 2799 visibility = ["//visibility:public"], 2800 ) 2801 `, 2802 }, 2803 { 2804 Path: "b/BUILD.bazel", 2805 Content: ` 2806 load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") 2807 load("@rules_proto//proto:defs.bzl", "proto_library") 2808 load("//:my.bzl", "my_go_library") 2809 2810 proto_library( 2811 name = "b_proto", 2812 srcs = ["b.proto"], 2813 visibility = ["//visibility:public"], 2814 deps = ["//a:a_proto"], 2815 ) 2816 2817 go_proto_library( 2818 name = "b_go_proto", 2819 importpath = "example.com/mapkind/b", 2820 proto = ":b_proto", 2821 visibility = ["//visibility:public"], 2822 deps = ["//a"], 2823 ) 2824 2825 my_go_library( 2826 name = "b", 2827 embed = [":b_go_proto"], 2828 importpath = "example.com/mapkind/b", 2829 visibility = ["//visibility:public"], 2830 ) 2831 `, 2832 }, 2833 }) 2834 } 2835 2836 // TestMinimalModuleCompatibilityAliases checks that importpath_aliases 2837 // are emitted for go_libraries when needed. This can't easily be checked 2838 // in language/go because the generator tests don't support running at 2839 // the repository root or with additional flags, both of which are required. 2840 func TestMinimalModuleCompatibilityAliases(t *testing.T) { 2841 files := []testtools.FileSpec{ 2842 { 2843 Path: "go.mod", 2844 Content: "module example.com/foo/v2", 2845 }, { 2846 Path: "foo.go", 2847 Content: "package foo", 2848 }, { 2849 Path: "bar/bar.go", 2850 Content: "package bar", 2851 }, 2852 } 2853 dir, cleanup := testtools.CreateFiles(t, files) 2854 defer cleanup() 2855 2856 args := []string{"update", "-repo_root", dir, "-go_prefix", "example.com/foo/v2", "-go_repository_mode", "-go_repository_module_mode"} 2857 if err := runGazelle(dir, args); err != nil { 2858 t.Fatal(err) 2859 } 2860 2861 testtools.CheckFiles(t, dir, []testtools.FileSpec{ 2862 { 2863 Path: "BUILD.bazel", 2864 Content: ` 2865 load("@io_bazel_rules_go//go:def.bzl", "go_library") 2866 2867 go_library( 2868 name = "foo", 2869 srcs = ["foo.go"], 2870 importpath = "example.com/foo/v2", 2871 importpath_aliases = ["example.com/foo"], 2872 visibility = ["//visibility:public"], 2873 ) 2874 `, 2875 }, { 2876 Path: "bar/BUILD.bazel", 2877 Content: ` 2878 load("@io_bazel_rules_go//go:def.bzl", "go_library") 2879 2880 go_library( 2881 name = "bar", 2882 srcs = ["bar.go"], 2883 importpath = "example.com/foo/v2/bar", 2884 importpath_aliases = ["example.com/foo/bar"], 2885 visibility = ["//visibility:public"], 2886 ) 2887 `, 2888 }, 2889 }) 2890 } 2891 2892 // TestGoImportVisibility checks that submodules implicitly declared with 2893 // go_repository rules in the repo config file (WORKSPACE) have visibility 2894 // for rules generated in internal directories where appropriate. 2895 // Verifies #619. 2896 func TestGoImportVisibility(t *testing.T) { 2897 files := []testtools.FileSpec{ 2898 { 2899 Path: "WORKSPACE", 2900 Content: ` 2901 go_repository( 2902 name = "com_example_m_logging", 2903 importpath = "example.com/m/logging", 2904 ) 2905 `, 2906 }, { 2907 Path: "internal/version/version.go", 2908 Content: "package version", 2909 }, { 2910 Path: "internal/version/version_test.go", 2911 Content: "package version", 2912 }, 2913 } 2914 dir, cleanup := testtools.CreateFiles(t, files) 2915 defer cleanup() 2916 2917 args := []string{"update", "-go_prefix", "example.com/m"} 2918 if err := runGazelle(dir, args); err != nil { 2919 t.Fatal(err) 2920 } 2921 2922 testtools.CheckFiles(t, dir, []testtools.FileSpec{{ 2923 Path: "internal/version/BUILD.bazel", 2924 Content: ` 2925 load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") 2926 2927 go_library( 2928 name = "version", 2929 srcs = ["version.go"], 2930 importpath = "example.com/m/internal/version", 2931 visibility = [ 2932 "//:__subpackages__", 2933 "@com_example_m_logging//:__subpackages__", 2934 ], 2935 ) 2936 2937 go_test( 2938 name = "version_test", 2939 srcs = ["version_test.go"], 2940 embed = [":version"], 2941 ) 2942 `, 2943 }}) 2944 } 2945 2946 // TestGoInternalVisibility_TopLevel checks that modules that are 2947 // named internal/ expand visibility to repos that have a sibling 2948 // importpath. 2949 // 2950 // Verifies #960 2951 func TestGoInternalVisibility_TopLevel(t *testing.T) { 2952 files := []testtools.FileSpec{ 2953 { 2954 Path: "WORKSPACE", 2955 Content: `go_repository(name="org_modernc_ccgo", importpath="modernc.org/ccgo")`, 2956 }, { 2957 Path: "BUILD.bazel", 2958 Content: `# gazelle:prefix modernc.org/internal`, 2959 }, { 2960 Path: "internal.go", 2961 Content: "package internal", 2962 }, { 2963 Path: "buffer/buffer.go", 2964 Content: "package buffer", 2965 }, 2966 } 2967 dir, cleanup := testtools.CreateFiles(t, files) 2968 defer cleanup() 2969 2970 args := []string{"update"} 2971 if err := runGazelle(dir, args); err != nil { 2972 t.Fatal(err) 2973 } 2974 2975 testtools.CheckFiles(t, dir, []testtools.FileSpec{ 2976 { 2977 Path: "BUILD.bazel", 2978 Content: ` 2979 load("@io_bazel_rules_go//go:def.bzl", "go_library") 2980 2981 # gazelle:prefix modernc.org/internal 2982 2983 go_library( 2984 name = "internal", 2985 srcs = ["internal.go"], 2986 importpath = "modernc.org/internal", 2987 visibility = [ 2988 "//:__subpackages__", 2989 "@org_modernc_ccgo//:__subpackages__", 2990 ], 2991 ) 2992 `, 2993 }, 2994 { 2995 Path: "buffer/BUILD.bazel", 2996 Content: ` 2997 load("@io_bazel_rules_go//go:def.bzl", "go_library") 2998 2999 go_library( 3000 name = "buffer", 3001 srcs = ["buffer.go"], 3002 importpath = "modernc.org/internal/buffer", 3003 visibility = [ 3004 "//:__subpackages__", 3005 "@org_modernc_ccgo//:__subpackages__", 3006 ], 3007 ) 3008 `, 3009 }, 3010 }) 3011 } 3012 3013 func TestImportCollision(t *testing.T) { 3014 files := []testtools.FileSpec{ 3015 { 3016 Path: "WORKSPACE", 3017 }, 3018 { 3019 Path: "go.mod", 3020 Content: ` 3021 module example.com/importcases 3022 3023 go 1.13 3024 3025 require ( 3026 github.com/Selvatico/go-mocket v1.0.7 3027 github.com/selvatico/go-mocket v1.0.7 3028 ) 3029 `, 3030 }, 3031 { 3032 Path: "go.sum", 3033 Content: ` 3034 github.com/Selvatico/go-mocket v1.0.7/go.mod h1:4gO2v+uQmsL+jzQgLANy3tyEFzaEzHlymVbZ3GP2Oes= 3035 github.com/selvatico/go-mocket v1.0.7/go.mod h1:7bSWzuNieCdUlanCVu3w0ppS0LvDtPAZmKBIlhoTcp8= 3036 `, 3037 }, 3038 } 3039 dir, cleanup := testtools.CreateFiles(t, files) 3040 defer cleanup() 3041 3042 args := []string{"update-repos", "--from_file=go.mod"} 3043 errMsg := "imports github.com/Selvatico/go-mocket and github.com/selvatico/go-mocket resolve to the same repository rule name com_github_selvatico_go_mocket" 3044 if err := runGazelle(dir, args); err == nil { 3045 t.Fatal("expected error, got nil") 3046 } else if err.Error() != errMsg { 3047 t.Errorf("want %s, got %s", errMsg, err.Error()) 3048 } 3049 } 3050 3051 func TestImportCollisionWithReplace(t *testing.T) { 3052 files := []testtools.FileSpec{ 3053 { 3054 Path: "WORKSPACE", 3055 Content: "# gazelle:repo bazel_gazelle", 3056 }, 3057 { 3058 Path: "go.mod", 3059 Content: ` 3060 module github.com/linzhp/go_examples/importcases 3061 3062 go 1.13 3063 3064 require ( 3065 github.com/Selvatico/go-mocket v1.0.7 3066 github.com/selvatico/go-mocket v0.0.0-00010101000000-000000000000 3067 ) 3068 3069 replace github.com/selvatico/go-mocket => github.com/Selvatico/go-mocket v1.0.7 3070 `, 3071 }, 3072 { 3073 Path: "go.sum", 3074 Content: ` 3075 github.com/Selvatico/go-mocket v1.0.7/go.mod h1:4gO2v+uQmsL+jzQgLANy3tyEFzaEzHlymVbZ3GP2Oes= 3076 `, 3077 }, 3078 } 3079 dir, cleanup := testtools.CreateFiles(t, files) 3080 defer cleanup() 3081 3082 args := []string{"update-repos", "--from_file=go.mod"} 3083 if err := runGazelle(dir, args); err != nil { 3084 t.Fatal(err) 3085 } 3086 testtools.CheckFiles(t, dir, []testtools.FileSpec{ 3087 { 3088 Path: "WORKSPACE", 3089 Content: ` 3090 load("@bazel_gazelle//:deps.bzl", "go_repository") 3091 3092 # gazelle:repo bazel_gazelle 3093 3094 go_repository( 3095 name = "com_github_selvatico_go_mocket", 3096 importpath = "github.com/selvatico/go-mocket", 3097 replace = "github.com/Selvatico/go-mocket", 3098 sum = "h1:sXuFMnMfVL9b/Os8rGXPgbOFbr4HJm8aHsulD/uMTUk=", 3099 version = "v1.0.7", 3100 ) 3101 `, 3102 }, 3103 }) 3104 } 3105 3106 // TestUpdateReposWithGlobalBuildTags is a regresion test for issue #711. 3107 // It also ensures that existings build_tags get merged with requested build_tags. 3108 func TestUpdateReposWithGlobalBuildTags(t *testing.T) { 3109 files := []testtools.FileSpec{ 3110 { 3111 Path: "WORKSPACE", 3112 Content: ` 3113 load("@bazel_gazelle//:deps.bzl", "go_repository") 3114 3115 # gazelle:repo bazel_gazelle 3116 3117 go_repository( 3118 name = "com_github_selvatico_go_mocket", 3119 build_tags = [ 3120 "bar", 3121 ], 3122 importpath = "github.com/selvatico/go-mocket", 3123 replace = "github.com/Selvatico/go-mocket", 3124 sum = "h1:sXuFMnMfVL9b/Os8rGXPgbOFbr4HJm8aHsulD/uMTUk=", 3125 version = "v1.0.7", 3126 ) 3127 `, 3128 }, 3129 { 3130 Path: "go.mod", 3131 Content: ` 3132 module github.com/linzhp/go_examples/importcases 3133 3134 go 1.13 3135 3136 require ( 3137 github.com/Selvatico/go-mocket v1.0.7 3138 github.com/selvatico/go-mocket v0.0.0-00010101000000-000000000000 3139 ) 3140 3141 replace github.com/selvatico/go-mocket => github.com/Selvatico/go-mocket v1.0.7 3142 `, 3143 }, 3144 { 3145 Path: "go.sum", 3146 Content: ` 3147 github.com/Selvatico/go-mocket v1.0.7/go.mod h1:4gO2v+uQmsL+jzQgLANy3tyEFzaEzHlymVbZ3GP2Oes= 3148 `, 3149 }, 3150 } 3151 dir, cleanup := testtools.CreateFiles(t, files) 3152 defer cleanup() 3153 3154 args := []string{"update-repos", "--from_file=go.mod", "--build_tags=bar,foo"} 3155 if err := runGazelle(dir, args); err != nil { 3156 t.Fatal(err) 3157 } 3158 testtools.CheckFiles(t, dir, []testtools.FileSpec{ 3159 { 3160 Path: "WORKSPACE", 3161 Content: ` 3162 load("@bazel_gazelle//:deps.bzl", "go_repository") 3163 3164 # gazelle:repo bazel_gazelle 3165 3166 go_repository( 3167 name = "com_github_selvatico_go_mocket", 3168 build_tags = [ 3169 "bar", 3170 "foo", 3171 ], 3172 importpath = "github.com/selvatico/go-mocket", 3173 replace = "github.com/Selvatico/go-mocket", 3174 sum = "h1:sXuFMnMfVL9b/Os8rGXPgbOFbr4HJm8aHsulD/uMTUk=", 3175 version = "v1.0.7", 3176 ) 3177 `, 3178 }, 3179 }) 3180 } 3181 3182 func TestMatchProtoLibrary(t *testing.T) { 3183 files := []testtools.FileSpec{ 3184 { 3185 Path: "WORKSPACE", 3186 }, 3187 { 3188 Path: "proto/BUILD.bazel", 3189 Content: ` 3190 load("@rules_proto//proto:defs.bzl", "proto_library") 3191 # gazelle:prefix example.com/foo 3192 3193 proto_library( 3194 name = "existing_proto", 3195 srcs = ["foo.proto"], 3196 ) 3197 `, 3198 }, 3199 { 3200 Path: "proto/foo.proto", 3201 Content: `syntax = "proto3";`, 3202 }, 3203 } 3204 dir, cleanup := testtools.CreateFiles(t, files) 3205 defer cleanup() 3206 3207 args := []string{"update"} 3208 if err := runGazelle(dir, args); err != nil { 3209 t.Fatal(err) 3210 } 3211 3212 testtools.CheckFiles(t, dir, []testtools.FileSpec{ 3213 { 3214 Path: "proto/BUILD.bazel", 3215 Content: ` 3216 load("@io_bazel_rules_go//go:def.bzl", "go_library") 3217 load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") 3218 load("@rules_proto//proto:defs.bzl", "proto_library") 3219 # gazelle:prefix example.com/foo 3220 3221 proto_library( 3222 name = "existing_proto", 3223 srcs = ["foo.proto"], 3224 visibility = ["//visibility:public"], 3225 ) 3226 3227 go_proto_library( 3228 name = "foo_go_proto", 3229 importpath = "example.com/foo", 3230 proto = ":existing_proto", 3231 visibility = ["//visibility:public"], 3232 ) 3233 3234 go_library( 3235 name = "foo", 3236 embed = [":foo_go_proto"], 3237 importpath = "example.com/foo", 3238 visibility = ["//visibility:public"], 3239 )`, 3240 }, 3241 }) 3242 } 3243 3244 func TestConfigLang(t *testing.T) { 3245 // Gazelle is run with "-lang=proto". 3246 files := []testtools.FileSpec{ 3247 {Path: "WORKSPACE"}, 3248 3249 // Verify that Gazelle does not create a BUILD file. 3250 {Path: "foo/foo.go", Content: "package foo"}, 3251 3252 // Verify that Gazelle only creates the proto rule. 3253 {Path: "pb/pb.go", Content: "package pb"}, 3254 {Path: "pb/pb.proto", Content: `syntax = "proto3";`}, 3255 3256 // Verify that Gazelle does create a BUILD file, because of the override. 3257 {Path: "bar/BUILD.bazel", Content: "# gazelle:lang"}, 3258 {Path: "bar/bar.go", Content: "package bar"}, 3259 {Path: "baz/BUILD.bazel", Content: "# gazelle:lang go,proto"}, 3260 {Path: "baz/baz.go", Content: "package baz"}, 3261 3262 // Verify that Gazelle does not index go_library rules in // or //baz/protos. 3263 // In those directories, lang is set to proto by flag and directive, respectively. 3264 // Confirm it does index and resolve a rule in a directory where go is activated. 3265 {Path: "invisible1.go", Content: "package invisible1"}, 3266 {Path: "BUILD.bazel", Content: ` 3267 load("@io_bazel_rules_go//go:def.bzl", "go_library") 3268 3269 # gazelle:prefix root 3270 3271 go_library( 3272 name = "go_default_library", 3273 srcs = ["invisible1.go"], 3274 importpath = "root", 3275 visibility = ["//visibility:public"], 3276 ) 3277 `}, 3278 {Path: "baz/protos/invisible2.go", Content: "package invisible2"}, 3279 {Path: "baz/protos/BUILD.bazel", Content: ` 3280 load("@io_bazel_rules_go//go:def.bzl", "go_library") 3281 3282 # gazelle:lang proto 3283 # gazelle:prefix github.com/rule_indexing/invisible2 3284 3285 go_library( 3286 name = "go_default_library", 3287 srcs = ["invisible2.go"], 3288 importpath = "github.com/rule_indexing/invisible2", 3289 visibility = ["//visibility:public"], 3290 ) 3291 `}, 3292 {Path: "visible/visible.go", Content: "package visible"}, 3293 {Path: "visible/BUILD.bazel", Content: ` 3294 load("@io_bazel_rules_go//go:def.bzl", "go_library") 3295 3296 # gazelle:lang go,proto 3297 # gazelle:prefix github.com/rule_indexing/visible 3298 3299 go_library( 3300 name = "go_default_library", 3301 srcs = ["visible.go"], 3302 importpath = "github.com/rule_indexing/visible", 3303 visibility = ["//visibility:public"], 3304 ) 3305 `}, 3306 {Path: "baz/test_no_index/test_no_index.go", Content: ` 3307 package test_no_index 3308 3309 import ( 3310 _ "github.com/rule_indexing/invisible1" 3311 _ "github.com/rule_indexing/invisible2" 3312 _ "github.com/rule_indexing/visible" 3313 ) 3314 `}, 3315 } 3316 3317 dir, cleanup := testtools.CreateFiles(t, files) 3318 defer cleanup() 3319 3320 args := []string{"-lang", "proto"} 3321 if err := runGazelle(dir, args); err != nil { 3322 t.Fatal(err) 3323 } 3324 3325 testtools.CheckFiles(t, dir, []testtools.FileSpec{ 3326 { 3327 Path: filepath.Join("foo", "BUILD.bazel"), 3328 NotExist: true, 3329 }, 3330 { 3331 Path: filepath.Join("pb", "BUILD.bazel"), 3332 Content: ` 3333 load("@rules_proto//proto:defs.bzl", "proto_library") 3334 3335 proto_library( 3336 name = "pb_proto", 3337 srcs = ["pb.proto"], 3338 visibility = ["//visibility:public"], 3339 )`, 3340 }, 3341 { 3342 Path: filepath.Join("bar", "BUILD.bazel"), 3343 Content: ` 3344 load("@io_bazel_rules_go//go:def.bzl", "go_library") 3345 3346 # gazelle:lang 3347 3348 go_library( 3349 name = "go_default_library", 3350 srcs = ["bar.go"], 3351 importpath = "root/bar", 3352 visibility = ["//visibility:public"], 3353 )`, 3354 }, 3355 { 3356 Path: filepath.Join("baz", "BUILD.bazel"), 3357 Content: ` 3358 load("@io_bazel_rules_go//go:def.bzl", "go_library") 3359 3360 # gazelle:lang go,proto 3361 3362 go_library( 3363 name = "go_default_library", 3364 srcs = ["baz.go"], 3365 importpath = "root/baz", 3366 visibility = ["//visibility:public"], 3367 )`, 3368 }, 3369 3370 {Path: "baz/test_no_index/BUILD.bazel", Content: ` 3371 load("@io_bazel_rules_go//go:def.bzl", "go_library") 3372 3373 go_library( 3374 name = "go_default_library", 3375 srcs = ["test_no_index.go"], 3376 importpath = "root/baz/test_no_index", 3377 visibility = ["//visibility:public"], 3378 deps = [ 3379 "//visible:go_default_library", 3380 "@com_github_rule_indexing_invisible1//:go_default_library", 3381 "@com_github_rule_indexing_invisible2//:go_default_library", 3382 ], 3383 ) 3384 `}, 3385 }) 3386 } 3387 3388 func TestUpdateRepos_LangFilter(t *testing.T) { 3389 dir, cleanup := testtools.CreateFiles(t, []testtools.FileSpec{ 3390 {Path: "WORKSPACE"}, 3391 }) 3392 defer cleanup() 3393 3394 args := []string{"update-repos", "-lang=proto", "github.com/sirupsen/logrus@v1.3.0"} 3395 err := runGazelle(dir, args) 3396 if err == nil { 3397 t.Fatal("expected an error, got none") 3398 } 3399 if !strings.Contains(err.Error(), "no languages can update repositories") { 3400 t.Fatalf("unexpected error: %+v", err) 3401 } 3402 } 3403 3404 func TestGoGenerateProto(t *testing.T) { 3405 files := []testtools.FileSpec{ 3406 { 3407 Path: "WORKSPACE", 3408 }, 3409 { 3410 Path: "proto/BUILD.bazel", 3411 Content: `# gazelle:go_generate_proto false 3412 # gazelle:prefix example.com/proto 3413 `, 3414 }, 3415 { 3416 Path: "proto/foo.proto", 3417 Content: `syntax = "proto3";`, 3418 }, 3419 { 3420 Path: "proto/foo.pb.go", 3421 Content: "package proto", 3422 }, 3423 } 3424 dir, cleanup := testtools.CreateFiles(t, files) 3425 defer cleanup() 3426 3427 args := []string{"update"} 3428 if err := runGazelle(dir, args); err != nil { 3429 t.Fatal(err) 3430 } 3431 3432 testtools.CheckFiles(t, dir, []testtools.FileSpec{ 3433 { 3434 Path: "proto/BUILD.bazel", 3435 Content: `load("@io_bazel_rules_go//go:def.bzl", "go_library") 3436 load("@rules_proto//proto:defs.bzl", "proto_library") 3437 3438 # gazelle:go_generate_proto false 3439 # gazelle:prefix example.com/proto 3440 3441 proto_library( 3442 name = "foo_proto", 3443 srcs = ["foo.proto"], 3444 visibility = ["//visibility:public"], 3445 ) 3446 3447 go_library( 3448 name = "proto", 3449 srcs = ["foo.pb.go"], 3450 importpath = "example.com/proto", 3451 visibility = ["//visibility:public"], 3452 )`, 3453 }, 3454 }) 3455 } 3456 3457 func TestGoMainLibraryRemoved(t *testing.T) { 3458 files := []testtools.FileSpec{ 3459 { 3460 Path: "WORKSPACE", 3461 }, 3462 { 3463 Path: "BUILD.bazel", 3464 Content: ` 3465 # gazelle:prefix example.com 3466 # gazelle:go_naming_convention import 3467 `, 3468 }, 3469 { 3470 Path: "cmd/foo/BUILD.bazel", 3471 Content: `load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") 3472 3473 go_library( 3474 name = "foo_lib", 3475 srcs = ["foo.go"], 3476 importpath = "example.com/cmd/foo", 3477 visibility = ["//visibility:private"], 3478 ) 3479 3480 go_binary( 3481 name = "foo", 3482 embed = [":foo_lib"], 3483 visibility = ["//visibility:public"], 3484 ) 3485 `, 3486 }, 3487 } 3488 dir, cleanup := testtools.CreateFiles(t, files) 3489 defer cleanup() 3490 3491 args := []string{"update"} 3492 if err := runGazelle(dir, args); err != nil { 3493 t.Fatal(err) 3494 } 3495 3496 testtools.CheckFiles(t, dir, []testtools.FileSpec{ 3497 { 3498 Path: "cmd/foo/BUILD.bazel", 3499 Content: "", 3500 }, 3501 }) 3502 } 3503 3504 func TestUpdateReposOldBoilerplateNewRepo(t *testing.T) { 3505 files := []testtools.FileSpec{ 3506 { 3507 Path: "WORKSPACE", 3508 Content: ` 3509 load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 3510 3511 http_archive( 3512 name = "io_bazel_rules_go", 3513 sha256 = "2697f6bc7c529ee5e6a2d9799870b9ec9eaeb3ee7d70ed50b87a2c2c97e13d9e", 3514 urls = [ 3515 "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.23.8/rules_go-v0.23.8.tar.gz", 3516 "https://github.com/bazelbuild/rules_go/releases/download/v0.23.8/rules_go-v0.23.8.tar.gz", 3517 ], 3518 ) 3519 3520 http_archive( 3521 name = "bazel_gazelle", 3522 sha256 = "cdb02a887a7187ea4d5a27452311a75ed8637379a1287d8eeb952138ea485f7d", 3523 urls = [ 3524 "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz", 3525 "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz", 3526 ], 3527 ) 3528 3529 load("@io_bazel_rules_go//go:deps.bzl", "go_rules_dependencies", "go_register_toolchains") 3530 3531 go_rules_dependencies() 3532 3533 go_register_toolchains() 3534 3535 load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies") 3536 3537 gazelle_dependencies() 3538 `, 3539 }, 3540 } 3541 3542 dir, cleanup := testtools.CreateFiles(t, files) 3543 defer cleanup() 3544 3545 args := []string{"update-repos", "golang.org/x/mod@v0.3.0"} 3546 if err := runGazelle(dir, args); err != nil { 3547 t.Fatal(err) 3548 } 3549 3550 testtools.CheckFiles(t, dir, []testtools.FileSpec{ 3551 { 3552 Path: "WORKSPACE", 3553 Content: ` 3554 load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 3555 3556 http_archive( 3557 name = "io_bazel_rules_go", 3558 sha256 = "2697f6bc7c529ee5e6a2d9799870b9ec9eaeb3ee7d70ed50b87a2c2c97e13d9e", 3559 urls = [ 3560 "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.23.8/rules_go-v0.23.8.tar.gz", 3561 "https://github.com/bazelbuild/rules_go/releases/download/v0.23.8/rules_go-v0.23.8.tar.gz", 3562 ], 3563 ) 3564 3565 http_archive( 3566 name = "bazel_gazelle", 3567 sha256 = "cdb02a887a7187ea4d5a27452311a75ed8637379a1287d8eeb952138ea485f7d", 3568 urls = [ 3569 "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz", 3570 "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz", 3571 ], 3572 ) 3573 3574 load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies") 3575 3576 go_rules_dependencies() 3577 3578 go_register_toolchains() 3579 3580 load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies", "go_repository") 3581 3582 go_repository( 3583 name = "org_golang_x_mod", 3584 importpath = "golang.org/x/mod", 3585 sum = "h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=", 3586 version = "v0.3.0", 3587 ) 3588 3589 gazelle_dependencies() 3590 `, 3591 }, 3592 }) 3593 } 3594 3595 func TestUpdateReposSkipsDirectiveRepo(t *testing.T) { 3596 files := []testtools.FileSpec{ 3597 { 3598 Path: "WORKSPACE", 3599 Content: ` 3600 load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 3601 3602 http_archive( 3603 name = "io_bazel_rules_go", 3604 sha256 = "2697f6bc7c529ee5e6a2d9799870b9ec9eaeb3ee7d70ed50b87a2c2c97e13d9e", 3605 urls = [ 3606 "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.23.8/rules_go-v0.23.8.tar.gz", 3607 "https://github.com/bazelbuild/rules_go/releases/download/v0.23.8/rules_go-v0.23.8.tar.gz", 3608 ], 3609 ) 3610 3611 http_archive( 3612 name = "bazel_gazelle", 3613 sha256 = "cdb02a887a7187ea4d5a27452311a75ed8637379a1287d8eeb952138ea485f7d", 3614 urls = [ 3615 "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz", 3616 "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz", 3617 ], 3618 ) 3619 3620 load("@io_bazel_rules_go//go:deps.bzl", "go_rules_dependencies", "go_register_toolchains") 3621 3622 go_rules_dependencies() 3623 3624 go_register_toolchains() 3625 3626 load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies") 3627 3628 gazelle_dependencies() 3629 3630 # gazelle:repository go_repository name=org_golang_x_mod importpath=golang.org/x/mod 3631 `, 3632 }, 3633 } 3634 3635 dir, cleanup := testtools.CreateFiles(t, files) 3636 defer cleanup() 3637 3638 args := []string{"update-repos", "golang.org/x/mod@v0.3.0"} 3639 if err := runGazelle(dir, args); err != nil { 3640 t.Fatal(err) 3641 } 3642 3643 testtools.CheckFiles(t, dir, []testtools.FileSpec{ 3644 { 3645 Path: "WORKSPACE", 3646 Content: ` 3647 load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 3648 3649 http_archive( 3650 name = "io_bazel_rules_go", 3651 sha256 = "2697f6bc7c529ee5e6a2d9799870b9ec9eaeb3ee7d70ed50b87a2c2c97e13d9e", 3652 urls = [ 3653 "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.23.8/rules_go-v0.23.8.tar.gz", 3654 "https://github.com/bazelbuild/rules_go/releases/download/v0.23.8/rules_go-v0.23.8.tar.gz", 3655 ], 3656 ) 3657 3658 http_archive( 3659 name = "bazel_gazelle", 3660 sha256 = "cdb02a887a7187ea4d5a27452311a75ed8637379a1287d8eeb952138ea485f7d", 3661 urls = [ 3662 "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz", 3663 "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz", 3664 ], 3665 ) 3666 3667 load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies") 3668 3669 go_rules_dependencies() 3670 3671 go_register_toolchains() 3672 3673 load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies") 3674 3675 gazelle_dependencies() 3676 3677 # gazelle:repository go_repository name=org_golang_x_mod importpath=golang.org/x/mod 3678 `, 3679 }, 3680 }) 3681 } 3682 3683 func TestUpdateReposOldBoilerplateNewMacro(t *testing.T) { 3684 files := []testtools.FileSpec{ 3685 { 3686 Path: "WORKSPACE", 3687 Content: ` 3688 load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 3689 3690 http_archive( 3691 name = "io_bazel_rules_go", 3692 sha256 = "2697f6bc7c529ee5e6a2d9799870b9ec9eaeb3ee7d70ed50b87a2c2c97e13d9e", 3693 urls = [ 3694 "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.23.8/rules_go-v0.23.8.tar.gz", 3695 "https://github.com/bazelbuild/rules_go/releases/download/v0.23.8/rules_go-v0.23.8.tar.gz", 3696 ], 3697 ) 3698 3699 http_archive( 3700 name = "bazel_gazelle", 3701 sha256 = "cdb02a887a7187ea4d5a27452311a75ed8637379a1287d8eeb952138ea485f7d", 3702 urls = [ 3703 "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz", 3704 "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz", 3705 ], 3706 ) 3707 3708 load("@io_bazel_rules_go//go:deps.bzl", "go_rules_dependencies", "go_register_toolchains") 3709 3710 go_rules_dependencies() 3711 3712 go_register_toolchains() 3713 3714 load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies") 3715 3716 gazelle_dependencies() 3717 `, 3718 }, 3719 } 3720 3721 dir, cleanup := testtools.CreateFiles(t, files) 3722 defer cleanup() 3723 3724 args := []string{"update-repos", "-to_macro=deps.bzl%deps", "golang.org/x/mod@v0.3.0"} 3725 if err := runGazelle(dir, args); err != nil { 3726 t.Fatal(err) 3727 } 3728 3729 testtools.CheckFiles(t, dir, []testtools.FileSpec{ 3730 { 3731 Path: "WORKSPACE", 3732 Content: ` 3733 load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 3734 3735 http_archive( 3736 name = "io_bazel_rules_go", 3737 sha256 = "2697f6bc7c529ee5e6a2d9799870b9ec9eaeb3ee7d70ed50b87a2c2c97e13d9e", 3738 urls = [ 3739 "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.23.8/rules_go-v0.23.8.tar.gz", 3740 "https://github.com/bazelbuild/rules_go/releases/download/v0.23.8/rules_go-v0.23.8.tar.gz", 3741 ], 3742 ) 3743 3744 http_archive( 3745 name = "bazel_gazelle", 3746 sha256 = "cdb02a887a7187ea4d5a27452311a75ed8637379a1287d8eeb952138ea485f7d", 3747 urls = [ 3748 "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz", 3749 "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz", 3750 ], 3751 ) 3752 3753 load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies") 3754 3755 go_rules_dependencies() 3756 3757 go_register_toolchains() 3758 3759 load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies") 3760 load("//:deps.bzl", "deps") 3761 3762 # gazelle:repository_macro deps.bzl%deps 3763 deps() 3764 3765 gazelle_dependencies() 3766 `, 3767 }, 3768 }) 3769 } 3770 3771 func TestUpdateReposNewBoilerplateNewRepo(t *testing.T) { 3772 files := []testtools.FileSpec{ 3773 { 3774 Path: "WORKSPACE", 3775 Content: ` 3776 load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 3777 3778 http_archive( 3779 name = "io_bazel_rules_go", 3780 sha256 = "2697f6bc7c529ee5e6a2d9799870b9ec9eaeb3ee7d70ed50b87a2c2c97e13d9e", 3781 urls = [ 3782 "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.23.8/rules_go-v0.23.8.tar.gz", 3783 "https://github.com/bazelbuild/rules_go/releases/download/v0.23.8/rules_go-v0.23.8.tar.gz", 3784 ], 3785 ) 3786 3787 http_archive( 3788 name = "bazel_gazelle", 3789 sha256 = "cdb02a887a7187ea4d5a27452311a75ed8637379a1287d8eeb952138ea485f7d", 3790 urls = [ 3791 "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz", 3792 "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz", 3793 ], 3794 ) 3795 3796 load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies") 3797 load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies") 3798 3799 go_rules_dependencies() 3800 3801 go_register_toolchains() 3802 3803 gazelle_dependencies() 3804 `, 3805 }, 3806 } 3807 3808 dir, cleanup := testtools.CreateFiles(t, files) 3809 defer cleanup() 3810 3811 args := []string{"update-repos", "golang.org/x/mod@v0.3.0"} 3812 if err := runGazelle(dir, args); err != nil { 3813 t.Fatal(err) 3814 } 3815 3816 testtools.CheckFiles(t, dir, []testtools.FileSpec{ 3817 { 3818 Path: "WORKSPACE", 3819 Content: ` 3820 load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 3821 3822 http_archive( 3823 name = "io_bazel_rules_go", 3824 sha256 = "2697f6bc7c529ee5e6a2d9799870b9ec9eaeb3ee7d70ed50b87a2c2c97e13d9e", 3825 urls = [ 3826 "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.23.8/rules_go-v0.23.8.tar.gz", 3827 "https://github.com/bazelbuild/rules_go/releases/download/v0.23.8/rules_go-v0.23.8.tar.gz", 3828 ], 3829 ) 3830 3831 http_archive( 3832 name = "bazel_gazelle", 3833 sha256 = "cdb02a887a7187ea4d5a27452311a75ed8637379a1287d8eeb952138ea485f7d", 3834 urls = [ 3835 "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz", 3836 "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz", 3837 ], 3838 ) 3839 3840 load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies", "go_repository") 3841 load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies") 3842 3843 go_repository( 3844 name = "org_golang_x_mod", 3845 importpath = "golang.org/x/mod", 3846 sum = "h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=", 3847 version = "v0.3.0", 3848 ) 3849 3850 go_rules_dependencies() 3851 3852 go_register_toolchains() 3853 3854 gazelle_dependencies() 3855 `, 3856 }, 3857 }) 3858 } 3859 3860 func TestUpdateReposNewBoilerplateNewMacro(t *testing.T) { 3861 files := []testtools.FileSpec{ 3862 { 3863 Path: "WORKSPACE", 3864 Content: ` 3865 load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 3866 3867 http_archive( 3868 name = "io_bazel_rules_go", 3869 sha256 = "2697f6bc7c529ee5e6a2d9799870b9ec9eaeb3ee7d70ed50b87a2c2c97e13d9e", 3870 urls = [ 3871 "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.23.8/rules_go-v0.23.8.tar.gz", 3872 "https://github.com/bazelbuild/rules_go/releases/download/v0.23.8/rules_go-v0.23.8.tar.gz", 3873 ], 3874 ) 3875 3876 http_archive( 3877 name = "bazel_gazelle", 3878 sha256 = "cdb02a887a7187ea4d5a27452311a75ed8637379a1287d8eeb952138ea485f7d", 3879 urls = [ 3880 "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz", 3881 "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz", 3882 ], 3883 ) 3884 3885 load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies") 3886 load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies") 3887 3888 go_rules_dependencies() 3889 3890 go_register_toolchains() 3891 3892 gazelle_dependencies() 3893 `, 3894 }, 3895 } 3896 3897 dir, cleanup := testtools.CreateFiles(t, files) 3898 defer cleanup() 3899 3900 args := []string{"update-repos", "-to_macro=deps.bzl%deps", "golang.org/x/mod@v0.3.0"} 3901 if err := runGazelle(dir, args); err != nil { 3902 t.Fatal(err) 3903 } 3904 3905 testtools.CheckFiles(t, dir, []testtools.FileSpec{ 3906 { 3907 Path: "WORKSPACE", 3908 Content: ` 3909 load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 3910 3911 http_archive( 3912 name = "io_bazel_rules_go", 3913 sha256 = "2697f6bc7c529ee5e6a2d9799870b9ec9eaeb3ee7d70ed50b87a2c2c97e13d9e", 3914 urls = [ 3915 "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.23.8/rules_go-v0.23.8.tar.gz", 3916 "https://github.com/bazelbuild/rules_go/releases/download/v0.23.8/rules_go-v0.23.8.tar.gz", 3917 ], 3918 ) 3919 3920 http_archive( 3921 name = "bazel_gazelle", 3922 sha256 = "cdb02a887a7187ea4d5a27452311a75ed8637379a1287d8eeb952138ea485f7d", 3923 urls = [ 3924 "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz", 3925 "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz", 3926 ], 3927 ) 3928 3929 load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies") 3930 load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies") 3931 load("//:deps.bzl", "deps") 3932 3933 # gazelle:repository_macro deps.bzl%deps 3934 deps() 3935 3936 go_rules_dependencies() 3937 3938 go_register_toolchains() 3939 3940 gazelle_dependencies() 3941 `, 3942 }, 3943 }) 3944 } 3945 3946 func TestExternalOnly(t *testing.T) { 3947 files := []testtools.FileSpec{ 3948 { 3949 Path: "WORKSPACE", 3950 }, 3951 { 3952 Path: "foo/foo.go", 3953 Content: `package foo 3954 import _ "golang.org/x/baz" 3955 `, 3956 }, 3957 { 3958 Path: "foo/foo_test.go", 3959 Content: `package foo_test 3960 import _ "golang.org/x/baz" 3961 import _ "example.com/foo" 3962 `, 3963 }, 3964 { 3965 Path: "foo/BUILD.bazel", 3966 Content: `# gazelle:prefix example.com/foo 3967 load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") 3968 3969 go_library( 3970 name = "foo", 3971 srcs = ["foo.go"], 3972 importpath = "example.com/foo", 3973 visibility = ["//visibility:public"], 3974 deps = ["@org_golang_x_baz//:go_default_library"], 3975 ) 3976 3977 go_test( 3978 name = "foo_test", 3979 srcs = ["foo_test.go"], 3980 embed = [":foo"], 3981 )`, 3982 }, 3983 } 3984 dir, cleanup := testtools.CreateFiles(t, files) 3985 defer cleanup() 3986 3987 var args []string 3988 if err := runGazelle(dir, args); err != nil { 3989 t.Fatal(err) 3990 } 3991 3992 testtools.CheckFiles(t, dir, []testtools.FileSpec{ 3993 { 3994 Path: "foo/BUILD.bazel", 3995 Content: `# gazelle:prefix example.com/foo 3996 load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") 3997 3998 go_library( 3999 name = "foo", 4000 srcs = ["foo.go"], 4001 importpath = "example.com/foo", 4002 visibility = ["//visibility:public"], 4003 deps = ["@org_golang_x_baz//:go_default_library"], 4004 ) 4005 4006 go_test( 4007 name = "foo_test", 4008 srcs = ["foo_test.go"], 4009 deps = [ 4010 ":foo", 4011 "@org_golang_x_baz//:go_default_library", 4012 ], 4013 )`, 4014 }, 4015 }) 4016 } 4017 4018 func TestFindRulesGoVersionWithWORKSPACE(t *testing.T) { 4019 files := []testtools.FileSpec{ 4020 { 4021 Path: "WORKSPACE", 4022 Content: ` 4023 load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 4024 4025 http_archive( 4026 name = "io_bazel_rules_go", 4027 sha256 = "7b9bbe3ea1fccb46dcfa6c3f3e29ba7ec740d8733370e21cdc8937467b4a4349", 4028 urls = [ 4029 "https://storage.googleapis.com/bazel-mirror/github.com/bazelbuild/rules_go/releases/download/v0.22.4/rules_go-v0.22.4.tar.gz", 4030 "https://github.com/bazelbuild/rules_go/releases/download/v0.22.4/rules_go-v0.22.4.tar.gz", 4031 ], 4032 ) 4033 `, 4034 }, 4035 { 4036 Path: "foo_illumos.go", 4037 Content: ` 4038 // illumos not supported in rules_go v0.22.4 4039 package foo 4040 `, 4041 }, 4042 { 4043 Path: "BUILD.bazel", 4044 Content: ` 4045 # gazelle:prefix example.com/foo 4046 `, 4047 }, 4048 } 4049 4050 dir, cleanup := testtools.CreateFiles(t, files) 4051 defer cleanup() 4052 4053 if err := runGazelle(dir, []string{"update"}); err != nil { 4054 t.Fatal(err) 4055 } 4056 4057 testtools.CheckFiles(t, dir, []testtools.FileSpec{ 4058 { 4059 Path: "BUILD.bazel", 4060 Content: ` 4061 # gazelle:prefix example.com/foo 4062 `, 4063 }, 4064 }) 4065 } 4066 4067 func TestPlatformSpecificEmbedsrcs(t *testing.T) { 4068 files := []testtools.FileSpec{ 4069 { 4070 Path: "WORKSPACE", 4071 }, 4072 { 4073 Path: "BUILD.bazel", 4074 Content: ` 4075 load("@io_bazel_rules_go//go:def.bzl", "go_library") 4076 4077 # gazelle:prefix example.com/foo 4078 4079 go_library( 4080 name = "foo", 4081 embedsrcs = ["deleted.txt"], 4082 importpath = "example.com/foo", 4083 srcs = ["foo.go"], 4084 ) 4085 `, 4086 }, 4087 { 4088 Path: "foo.go", 4089 Content: ` 4090 // +build windows 4091 4092 package foo 4093 4094 import _ "embed" 4095 4096 //go:embed windows.txt 4097 var s string 4098 `, 4099 }, 4100 { 4101 Path: "windows.txt", 4102 }, 4103 } 4104 4105 dir, cleanup := testtools.CreateFiles(t, files) 4106 defer cleanup() 4107 4108 if err := runGazelle(dir, []string{"update"}); err != nil { 4109 t.Fatal(err) 4110 } 4111 4112 testtools.CheckFiles(t, dir, []testtools.FileSpec{ 4113 { 4114 Path: "BUILD.bazel", 4115 Content: ` 4116 load("@io_bazel_rules_go//go:def.bzl", "go_library") 4117 4118 # gazelle:prefix example.com/foo 4119 4120 go_library( 4121 name = "foo", 4122 srcs = ["foo.go"], 4123 embedsrcs = select({ 4124 "@io_bazel_rules_go//go/platform:windows": [ 4125 "windows.txt", 4126 ], 4127 "//conditions:default": [], 4128 }), 4129 importpath = "example.com/foo", 4130 visibility = ["//visibility:public"], 4131 ) 4132 `, 4133 }, 4134 }) 4135 } 4136 4137 // Checks that go:embed directives with spaces and quotes are parsed correctly. 4138 // This probably belongs in //language/go:go_test, but we need file names with 4139 // spaces, and Bazel doesn't allow those in runfiles, which that test depends 4140 // on. 4141 func TestQuotedEmbedsrcs(t *testing.T) { 4142 files := []testtools.FileSpec{ 4143 { 4144 Path: "WORKSPACE", 4145 }, 4146 { 4147 Path: "BUILD.bazel", 4148 Content: "# gazelle:prefix example.com/foo", 4149 }, 4150 { 4151 Path: "foo.go", 4152 Content: strings.Join([]string{ 4153 "package foo", 4154 "import \"embed\"", 4155 "//go:embed q1.txt q2.txt \"q 3.txt\" `q 4.txt`", 4156 "var fs embed.FS", 4157 }, "\n"), 4158 }, 4159 { 4160 Path: "q1.txt", 4161 }, 4162 { 4163 Path: "q2.txt", 4164 }, 4165 { 4166 Path: "q 3.txt", 4167 }, 4168 { 4169 Path: "q 4.txt", 4170 }, 4171 } 4172 dir, cleanup := testtools.CreateFiles(t, files) 4173 defer cleanup() 4174 4175 if err := runGazelle(dir, []string{"update"}); err != nil { 4176 t.Fatal(err) 4177 } 4178 4179 testtools.CheckFiles(t, dir, []testtools.FileSpec{{ 4180 Path: "BUILD.bazel", 4181 Content: ` 4182 load("@io_bazel_rules_go//go:def.bzl", "go_library") 4183 4184 # gazelle:prefix example.com/foo 4185 4186 go_library( 4187 name = "foo", 4188 srcs = ["foo.go"], 4189 embedsrcs = [ 4190 "q 3.txt", 4191 "q 4.txt", 4192 "q1.txt", 4193 "q2.txt", 4194 ], 4195 importpath = "example.com/foo", 4196 visibility = ["//visibility:public"], 4197 ) 4198 `, 4199 }}) 4200 } 4201 4202 // TestUpdateReposDoesNotModifyGoSum verifies that commands executed by 4203 // update-repos do not modify go.sum, particularly 'go mod download' when 4204 // a sum is missing. Verifies #990. 4205 // 4206 // This could also be tested in language/go/update_import_test.go, but that 4207 // test relies on stubs for speed, and it's important to run the real 4208 // go command here. 4209 func TestUpdateReposDoesNotModifyGoSum(t *testing.T) { 4210 if testing.Short() { 4211 // Test may download small files over network. 4212 t.Skip() 4213 } 4214 goSumFile := testtools.FileSpec{ 4215 // go.sum only contains the sum for the mod file, not the content. 4216 // This is common for transitive dependencies not needed by the main module. 4217 Path: "go.sum", 4218 Content: "golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\n", 4219 } 4220 files := []testtools.FileSpec{ 4221 { 4222 Path: "WORKSPACE", 4223 Content: "# gazelle:repo bazel_gazelle", 4224 }, 4225 { 4226 Path: "go.mod", 4227 Content: ` 4228 module test 4229 4230 go 1.16 4231 4232 require golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 4233 `, 4234 }, 4235 goSumFile, 4236 } 4237 dir, cleanup := testtools.CreateFiles(t, files) 4238 defer cleanup() 4239 4240 if err := runGazelle(dir, []string{"update-repos", "-from_file=go.mod"}); err != nil { 4241 t.Fatal(err) 4242 } 4243 testtools.CheckFiles(t, dir, []testtools.FileSpec{goSumFile}) 4244 } 4245 4246 func TestResolveGoStaticFromGoMod(t *testing.T) { 4247 dir, cleanup := testtools.CreateFiles(t, []testtools.FileSpec{ 4248 {Path: "WORKSPACE"}, 4249 { 4250 Path: "go.mod", 4251 Content: ` 4252 module example.com/use 4253 4254 go 1.19 4255 4256 require example.com/dep v1.0.0 4257 `, 4258 }, 4259 { 4260 Path: "use.go", 4261 Content: ` 4262 package use 4263 4264 import _ "example.com/dep/pkg" 4265 `, 4266 }, 4267 }) 4268 defer cleanup() 4269 4270 args := []string{ 4271 "-go_prefix=example.com/use", 4272 "-external=static", 4273 "-go_naming_convention_external=import", 4274 } 4275 if err := runGazelle(dir, args); err != nil { 4276 t.Fatal(err) 4277 } 4278 4279 testtools.CheckFiles(t, dir, []testtools.FileSpec{ 4280 { 4281 Path: "BUILD.bazel", 4282 Content: ` 4283 load("@io_bazel_rules_go//go:def.bzl", "go_library") 4284 4285 go_library( 4286 name = "use", 4287 srcs = ["use.go"], 4288 importpath = "example.com/use", 4289 visibility = ["//visibility:public"], 4290 deps = ["@com_example_dep//pkg"], 4291 ) 4292 `, 4293 }, 4294 }) 4295 } 4296 4297 func TestMigrateSelectFromWorkspaceToBzlmod(t *testing.T) { 4298 dir, cleanup := testtools.CreateFiles(t, []testtools.FileSpec{ 4299 {Path: "WORKSPACE"}, 4300 { 4301 Path: "MODULE.bazel", 4302 Content: `bazel_dep(name = "rules_go", version = "0.39.1", repo_name = "my_rules_go")`, 4303 }, 4304 { 4305 Path: "BUILD", 4306 Content: `load("@io_bazel_rules_go//go:def.bzl", "go_library") 4307 4308 go_library( 4309 name = "foo", 4310 srcs = [ 4311 "bar.go", 4312 "foo.go", 4313 "foo_android.go", 4314 "foo_android_build_tag.go", 4315 ], 4316 importpath = "example.com/foo", 4317 visibility = ["//visibility:public"], 4318 deps = select({ 4319 "@io_bazel_rules_go//go/platform:android": [ 4320 "//outer", 4321 "//outer/inner", 4322 "//outer_android_build_tag", 4323 "//outer_android_suffix", 4324 "@com_github_jr_hacker_tools//:go_default_library", 4325 ], 4326 "@io_bazel_rules_go//go/platform:linux": [ 4327 "//outer", 4328 "//outer/inner", 4329 "@com_github_jr_hacker_tools//:go_default_library", 4330 ], 4331 "//conditions:default": [], 4332 }), 4333 ) 4334 `, 4335 }, 4336 { 4337 Path: "foo.go", 4338 Content: ` 4339 // +build linux 4340 4341 package foo 4342 4343 import ( 4344 _ "example.com/foo/outer" 4345 _ "example.com/foo/outer/inner" 4346 _ "github.com/jr_hacker/tools" 4347 ) 4348 `, 4349 }, 4350 { 4351 Path: "foo_android_build_tag.go", 4352 Content: ` 4353 // +build android 4354 4355 package foo 4356 4357 import ( 4358 _ "example.com/foo/outer_android_build_tag" 4359 ) 4360 `, 4361 }, 4362 { 4363 Path: "foo_android.go", 4364 Content: ` 4365 package foo 4366 4367 import ( 4368 _ "example.com/foo/outer_android_suffix" 4369 ) 4370 `, 4371 }, 4372 { 4373 Path: "bar.go", 4374 Content: `// +build linux 4375 4376 package foo 4377 `, 4378 }, 4379 {Path: "outer/outer.go", Content: "package outer"}, 4380 {Path: "outer_android_build_tag/outer.go", Content: "package outer_android_build_tag"}, 4381 {Path: "outer_android_suffix/outer.go", Content: "package outer_android_suffix"}, 4382 {Path: "outer/inner/inner.go", Content: "package inner"}, 4383 }) 4384 want := `load("@io_bazel_rules_go//go:def.bzl", "go_library") 4385 4386 go_library( 4387 name = "foo", 4388 srcs = [ 4389 "bar.go", 4390 "foo.go", 4391 "foo_android.go", 4392 "foo_android_build_tag.go", 4393 ], 4394 importpath = "example.com/foo", 4395 visibility = ["//visibility:public"], 4396 deps = select({ 4397 "@my_rules_go//go/platform:android": [ 4398 "//outer", 4399 "//outer/inner", 4400 "//outer_android_build_tag", 4401 "//outer_android_suffix", 4402 "@com_github_jr_hacker_tools//:go_default_library", 4403 ], 4404 "@my_rules_go//go/platform:linux": [ 4405 "//outer", 4406 "//outer/inner", 4407 "@com_github_jr_hacker_tools//:go_default_library", 4408 ], 4409 "//conditions:default": [], 4410 }), 4411 ) 4412 ` 4413 defer cleanup() 4414 4415 if err := runGazelle(dir, []string{"-go_prefix", "example.com/foo"}); err != nil { 4416 t.Fatal(err) 4417 } 4418 if got, err := os.ReadFile(filepath.Join(dir, "BUILD")); err != nil { 4419 t.Fatal(err) 4420 } else if string(got) != want { 4421 t.Fatalf("got %s ; want %s; diff %s", string(got), want, cmp.Diff(string(got), want)) 4422 } 4423 } 4424 4425 func TestUpdateReposWithBzlmodWithToMacro(t *testing.T) { 4426 dir, cleanup := testtools.CreateFiles(t, []testtools.FileSpec{ 4427 {Path: "WORKSPACE"}, 4428 { 4429 Path: "go.mod", 4430 Content: ` 4431 module example.com/foo/v2 4432 4433 go 1.19 4434 4435 require ( 4436 github.com/stretchr/testify v1.8.4 4437 ) 4438 `, 4439 }, 4440 }) 4441 4442 t.Cleanup(cleanup) 4443 4444 args := []string{ 4445 "update-repos", 4446 "-from_file=go.mod", 4447 "-to_macro=go_deps.bzl%my_go_deps", 4448 "-bzlmod", 4449 } 4450 if err := runGazelle(dir, args); err != nil { 4451 t.Fatal(err) 4452 } 4453 4454 // Confirm that the WORKSPACE is still empty 4455 want := "" 4456 if got, err := os.ReadFile(filepath.Join(dir, "WORKSPACE")); err != nil { 4457 t.Fatal(err) 4458 } else if string(got) != want { 4459 t.Fatalf("got %s ; want %s; diff %s", string(got), want, cmp.Diff(string(got), want)) 4460 } 4461 4462 // Confirm that the macro file was written 4463 want = `load("@bazel_gazelle//:deps.bzl", "go_repository") 4464 4465 def my_go_deps(): 4466 go_repository( 4467 name = "com_github_stretchr_testify", 4468 importpath = "github.com/stretchr/testify", 4469 sum = "h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=", 4470 version = "v1.8.4", 4471 ) 4472 ` 4473 if got, err := os.ReadFile(filepath.Join(dir, "go_deps.bzl")); err != nil { 4474 t.Fatal(err) 4475 } else if string(got) != want { 4476 t.Fatalf("got %s ; want %s; diff %s", string(got), want, cmp.Diff(string(got), want)) 4477 } 4478 } 4479 4480 func TestUpdateReposWithBzlmodWithoutToMacro(t *testing.T) { 4481 dir, cleanup := testtools.CreateFiles(t, []testtools.FileSpec{ 4482 {Path: "WORKSPACE"}, 4483 { 4484 Path: "go.mod", 4485 Content: ` 4486 module example.com/foo/v2 4487 4488 go 1.19 4489 4490 require ( 4491 github.com/stretchr/testify v1.8.4 4492 ) 4493 `, 4494 }, 4495 }) 4496 4497 t.Cleanup(cleanup) 4498 4499 args := []string{ 4500 "update-repos", 4501 "-from_file=go.mod", 4502 "-bzlmod", 4503 } 4504 if err := runGazelle(dir, args); err != nil { 4505 t.Fatal(err) 4506 } 4507 4508 // Confirm that the WORKSPACE is still empty 4509 want := "" 4510 if got, err := os.ReadFile(filepath.Join(dir, "WORKSPACE")); err != nil { 4511 t.Fatal(err) 4512 } else if string(got) != want { 4513 t.Fatalf("got %s ; want %s; diff %s", string(got), want, cmp.Diff(string(got), want)) 4514 } 4515 }