github.com/afking/bazel-gazelle@v0.0.0-20180301150245-c02bc0f529e8/internal/packages/walk_test.go (about) 1 /* Copyright 2016 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 package packages_test 17 18 import ( 19 "io/ioutil" 20 "os" 21 "path" 22 "path/filepath" 23 "reflect" 24 "strings" 25 "testing" 26 27 "github.com/bazelbuild/bazel-gazelle/internal/config" 28 "github.com/bazelbuild/bazel-gazelle/internal/packages" 29 bf "github.com/bazelbuild/buildtools/build" 30 ) 31 32 func tempDir() (string, error) { 33 return ioutil.TempDir(os.Getenv("TEST_TMPDIR"), "walk_test") 34 } 35 36 type fileSpec struct { 37 path, content, symlink string 38 } 39 40 func checkFiles(t *testing.T, files []fileSpec, goPrefix string, want []*packages.Package) { 41 dir, err := createFiles(files) 42 if err != nil { 43 t.Fatalf("createFiles() failed with %v; want success", err) 44 } 45 defer os.RemoveAll(dir) 46 47 for _, p := range want { 48 p.Dir = filepath.Join(dir, filepath.FromSlash(p.Rel)) 49 } 50 51 c := &config.Config{ 52 RepoRoot: dir, 53 GoPrefix: goPrefix, 54 Dirs: []string{dir}, 55 ValidBuildFileNames: config.DefaultValidBuildFileNames, 56 } 57 got := walkPackages(c) 58 checkPackages(t, got, want) 59 } 60 61 func createFiles(files []fileSpec) (string, error) { 62 dir, err := tempDir() 63 if err != nil { 64 return "", err 65 } 66 for _, f := range files { 67 path := filepath.Join(dir, f.path) 68 if strings.HasSuffix(f.path, "/") { 69 if err := os.MkdirAll(path, 0700); err != nil { 70 return dir, err 71 } 72 continue 73 } 74 if err := os.MkdirAll(filepath.Dir(path), 0700); err != nil { 75 return "", err 76 } 77 if f.symlink != "" { 78 if err := os.Symlink(f.symlink, path); err != nil { 79 return "", err 80 } 81 continue 82 } 83 if err := ioutil.WriteFile(path, []byte(f.content), 0600); err != nil { 84 return "", err 85 } 86 } 87 return dir, nil 88 } 89 90 func walkPackages(c *config.Config) []*packages.Package { 91 var pkgs []*packages.Package 92 packages.Walk(c, c.RepoRoot, func(_, _ string, _ *config.Config, pkg *packages.Package, _ *bf.File, _ bool) { 93 if pkg != nil { 94 pkgs = append(pkgs, pkg) 95 } 96 }) 97 return pkgs 98 } 99 100 func checkPackages(t *testing.T, got []*packages.Package, want []*packages.Package) { 101 if len(got) != len(want) { 102 names := []string{} 103 for _, p := range got { 104 names = append(names, p.Name) 105 } 106 t.Fatalf("got %d packages %v; want %d", len(got), names, len(want)) 107 } 108 for i := 0; i < len(got); i++ { 109 checkPackage(t, got[i], want[i]) 110 } 111 } 112 113 func checkPackage(t *testing.T, got, want *packages.Package) { 114 // TODO: Implement Stringer or Formatter to get more readable output. 115 if !reflect.DeepEqual(got, want) { 116 t.Errorf("for package %q, got %#v; want %#v", want.Name, got, want) 117 } 118 } 119 120 func TestWalkEmpty(t *testing.T) { 121 files := []fileSpec{ 122 {path: "a/foo.c"}, 123 {path: "b/BUILD"}, 124 {path: "c/"}, 125 } 126 want := []*packages.Package{} 127 checkFiles(t, files, "", want) 128 } 129 130 func TestWalkSimple(t *testing.T) { 131 files := []fileSpec{{path: "lib.go", content: "package lib"}} 132 want := []*packages.Package{ 133 { 134 Name: "lib", 135 ImportPath: "example.com/repo", 136 Library: packages.GoTarget{ 137 Sources: packages.PlatformStrings{ 138 Generic: []string{"lib.go"}, 139 }, 140 }, 141 }, 142 } 143 checkFiles(t, files, "example.com/repo", want) 144 } 145 146 func TestWalkNested(t *testing.T) { 147 files := []fileSpec{ 148 {path: "a/foo.go", content: "package a"}, 149 {path: "b/c/bar.go", content: "package c"}, 150 {path: "b/d/baz.go", content: "package main"}, 151 } 152 want := []*packages.Package{ 153 { 154 Name: "a", 155 Rel: "a", 156 ImportPath: "example.com/repo/a", 157 Library: packages.GoTarget{ 158 Sources: packages.PlatformStrings{ 159 Generic: []string{"foo.go"}, 160 }, 161 }, 162 }, 163 { 164 Name: "c", 165 Rel: "b/c", 166 ImportPath: "example.com/repo/b/c", 167 Library: packages.GoTarget{ 168 Sources: packages.PlatformStrings{ 169 Generic: []string{"bar.go"}, 170 }, 171 }, 172 }, 173 { 174 Name: "main", 175 Rel: "b/d", 176 ImportPath: "example.com/repo/b/d", 177 Library: packages.GoTarget{ 178 Sources: packages.PlatformStrings{ 179 Generic: []string{"baz.go"}, 180 }, 181 }, 182 }, 183 } 184 checkFiles(t, files, "example.com/repo", want) 185 } 186 187 func TestProtoOnly(t *testing.T) { 188 files := []fileSpec{ 189 {path: "a/a.proto"}, 190 } 191 want := []*packages.Package{ 192 { 193 Name: "a", 194 Rel: "a", 195 ImportPath: "example.com/repo/a", 196 Proto: packages.ProtoTarget{ 197 Sources: packages.PlatformStrings{ 198 Generic: []string{"a.proto"}, 199 }, 200 }, 201 }, 202 } 203 checkFiles(t, files, "example.com/repo", want) 204 } 205 206 func TestMultiplePackagesWithDefault(t *testing.T) { 207 files := []fileSpec{ 208 {path: "a/a.go", content: "package a"}, 209 {path: "a/b.go", content: "package b"}, 210 } 211 want := []*packages.Package{ 212 { 213 Name: "a", 214 Rel: "a", 215 ImportPath: "example.com/repo/a", 216 Library: packages.GoTarget{ 217 Sources: packages.PlatformStrings{ 218 Generic: []string{"a.go"}, 219 }, 220 }, 221 }, 222 } 223 checkFiles(t, files, "example.com/repo", want) 224 } 225 226 func TestMultiplePackagesWithoutDefault(t *testing.T) { 227 files := []fileSpec{ 228 {path: "a/b.go", content: "package b"}, 229 {path: "a/c.go", content: "package c"}, 230 } 231 dir, err := createFiles(files) 232 if err != nil { 233 t.Fatalf("createFiles() failed with %v; want success", err) 234 } 235 defer os.RemoveAll(dir) 236 237 c := &config.Config{ 238 RepoRoot: dir, 239 Dirs: []string{dir}, 240 ValidBuildFileNames: config.DefaultValidBuildFileNames, 241 } 242 got := walkPackages(c) 243 if len(got) > 0 { 244 t.Errorf("got %v; want empty slice", got) 245 } 246 } 247 248 func TestMultiplePackagesWithProtoDefault(t *testing.T) { 249 files := []fileSpec{ 250 {path: "a/a.proto", content: `syntax = "proto2"; 251 package a; 252 `}, 253 {path: "a/b.go", content: "package b"}, 254 } 255 want := []*packages.Package{ 256 { 257 Name: "a", 258 Rel: "a", 259 ImportPath: "example.com/repo/a", 260 Proto: packages.ProtoTarget{ 261 Sources: packages.PlatformStrings{ 262 Generic: []string{"a.proto"}, 263 }, 264 }, 265 }, 266 } 267 checkFiles(t, files, "example.com/repo", want) 268 } 269 270 func TestRootWithPrefix(t *testing.T) { 271 files := []fileSpec{ 272 {path: "a.go", content: "package a"}, 273 {path: "b.go", content: "package b"}, 274 } 275 want := []*packages.Package{ 276 { 277 Name: "a", 278 ImportPath: "example.com/a", 279 Library: packages.GoTarget{ 280 Sources: packages.PlatformStrings{ 281 Generic: []string{"a.go"}, 282 }, 283 }, 284 }, 285 } 286 checkFiles(t, files, "example.com/a", want) 287 } 288 289 func TestRootWithoutPrefix(t *testing.T) { 290 files := []fileSpec{ 291 {path: "a.go", content: "package a"}, 292 {path: "b.go", content: "package b"}, 293 } 294 dir, err := createFiles(files) 295 if err != nil { 296 t.Fatalf("createFiles() failed with %v; want success", err) 297 } 298 defer os.RemoveAll(dir) 299 300 c := &config.Config{ 301 RepoRoot: dir, 302 Dirs: []string{dir}, 303 ValidBuildFileNames: config.DefaultValidBuildFileNames, 304 } 305 got := walkPackages(c) 306 if len(got) > 0 { 307 t.Errorf("got %v; want empty slice", got) 308 } 309 } 310 311 func TestVendorResetsPrefix(t *testing.T) { 312 files := []fileSpec{ 313 {path: "vendor/"}, 314 {path: "sub/vendor/"}, 315 } 316 dir, err := createFiles(files) 317 if err != nil { 318 t.Fatal(err) 319 } 320 defer os.RemoveAll(dir) 321 322 basePrefix := "example.com/repo" 323 c := &config.Config{ 324 RepoRoot: dir, 325 Dirs: []string{dir}, 326 ValidBuildFileNames: config.DefaultValidBuildFileNames, 327 GoPrefix: basePrefix, 328 } 329 packages.Walk(c, c.RepoRoot, func(_, rel string, c *config.Config, _ *packages.Package, _ *bf.File, _ bool) { 330 if path.Base(rel) != "vendor" { 331 return 332 } 333 if c.GoPrefix != "" { 334 t.Errorf("in %q, GoPrefix not reset", rel) 335 } 336 if c.GoPrefixRel != rel { 337 t.Errorf("in %q, GoPrefixRel not set", rel) 338 } 339 }) 340 if c.GoPrefix != basePrefix { 341 t.Errorf("prefix in base configuration was modified: %q", c.GoPrefix) 342 } 343 } 344 345 func TestPrefixEmpty(t *testing.T) { 346 files := []fileSpec{ 347 {path: "a.go", content: "package foo"}, 348 } 349 want := []*packages.Package{} 350 checkFiles(t, files, "", want) 351 } 352 353 func TestProtoImportPath(t *testing.T) { 354 files := []fileSpec{{ 355 path: "foo.proto", 356 content: `syntax = "proto3"; 357 option go_package = "example.com/repo/foo"; 358 `, 359 }} 360 want := []*packages.Package{{ 361 Name: "foo", 362 ImportPath: "example.com/repo/foo", 363 Proto: packages.ProtoTarget{ 364 Sources: packages.PlatformStrings{ 365 Generic: []string{"foo.proto"}, 366 }, 367 }, 368 }} 369 checkFiles(t, files, "", want) 370 } 371 372 func TestTestdata(t *testing.T) { 373 files := []fileSpec{ 374 {path: "raw/testdata/"}, 375 {path: "raw/a.go", content: "package raw"}, 376 {path: "with_build/testdata/BUILD"}, 377 {path: "with_build/a.go", content: "package with_build"}, 378 {path: "with_build_bazel/testdata/BUILD.bazel"}, 379 {path: "with_build_bazel/a.go", content: "package with_build_bazel"}, 380 {path: "with_build_nested/testdata/x/BUILD"}, 381 {path: "with_build_nested/a.go", content: "package with_build_nested"}, 382 {path: "with_go/testdata/a.go", content: "package testdata"}, 383 {path: "with_go/a.go", content: "package with_go"}, 384 } 385 want := []*packages.Package{ 386 { 387 Name: "raw", 388 Rel: "raw", 389 ImportPath: "example.com/repo/raw", 390 Library: packages.GoTarget{ 391 Sources: packages.PlatformStrings{ 392 Generic: []string{"a.go"}, 393 }, 394 }, 395 HasTestdata: true, 396 }, 397 { 398 Name: "with_build", 399 Rel: "with_build", 400 ImportPath: "example.com/repo/with_build", 401 Library: packages.GoTarget{ 402 Sources: packages.PlatformStrings{ 403 Generic: []string{"a.go"}, 404 }, 405 }, 406 HasTestdata: false, 407 }, 408 { 409 Name: "with_build_bazel", 410 Rel: "with_build_bazel", 411 ImportPath: "example.com/repo/with_build_bazel", 412 Library: packages.GoTarget{ 413 Sources: packages.PlatformStrings{ 414 Generic: []string{"a.go"}, 415 }, 416 }, 417 HasTestdata: false, 418 }, 419 { 420 Name: "with_build_nested", 421 Rel: "with_build_nested", 422 ImportPath: "example.com/repo/with_build_nested", 423 Library: packages.GoTarget{ 424 Sources: packages.PlatformStrings{ 425 Generic: []string{"a.go"}, 426 }, 427 }, 428 HasTestdata: false, 429 }, 430 { 431 Name: "testdata", 432 Rel: "with_go/testdata", 433 ImportPath: "example.com/repo/with_go/testdata", 434 Library: packages.GoTarget{ 435 Sources: packages.PlatformStrings{ 436 Generic: []string{"a.go"}, 437 }, 438 }, 439 }, 440 { 441 Name: "with_go", 442 Rel: "with_go", 443 ImportPath: "example.com/repo/with_go", 444 Library: packages.GoTarget{ 445 Sources: packages.PlatformStrings{ 446 Generic: []string{"a.go"}, 447 }, 448 }, 449 HasTestdata: false, 450 }, 451 } 452 checkFiles(t, files, "example.com/repo", want) 453 } 454 455 func TestGenerated(t *testing.T) { 456 files := []fileSpec{ 457 { 458 path: "gen/BUILD", 459 content: ` 460 genrule( 461 name = "from_genrule", 462 outs = ["foo.go", "bar.go", "w.txt", "x.c", "y.s", "z.S"], 463 ) 464 465 gen_other( 466 name = "from_gen_other", 467 out = "baz.go", 468 ) 469 `, 470 }, 471 { 472 path: "gen/foo.go", 473 content: `package foo 474 475 import "github.com/jr_hacker/stuff" 476 `, 477 }, 478 } 479 want := []*packages.Package{ 480 { 481 Name: "foo", 482 Rel: "gen", 483 ImportPath: "example.com/repo/gen", 484 Library: packages.GoTarget{ 485 Sources: packages.PlatformStrings{ 486 Generic: []string{"bar.go", "baz.go", "foo.go", "y.s"}, 487 }, 488 Imports: packages.PlatformStrings{ 489 Generic: []string{"github.com/jr_hacker/stuff"}, 490 }, 491 }, 492 }, 493 } 494 checkFiles(t, files, "example.com/repo", want) 495 } 496 497 func TestGeneratedCgo(t *testing.T) { 498 files := []fileSpec{ 499 { 500 path: "gen/BUILD", 501 content: ` 502 genrule( 503 name = "from_genrule", 504 outs = ["foo.go", "bar.go", "w.txt", "x.c", "y.s", "z.S"], 505 ) 506 507 gen_other( 508 name = "from_gen_other", 509 out = "baz.go", 510 ) 511 `, 512 }, 513 { 514 path: "gen/foo.go", 515 content: `package foo 516 517 import "C" 518 519 import "github.com/jr_hacker/stuff" 520 `, 521 }, 522 } 523 want := []*packages.Package{ 524 { 525 Name: "foo", 526 Rel: "gen", 527 ImportPath: "example.com/repo/gen", 528 Library: packages.GoTarget{ 529 Sources: packages.PlatformStrings{ 530 Generic: []string{"bar.go", "baz.go", "foo.go", "x.c", "y.s", "z.S"}, 531 }, 532 Imports: packages.PlatformStrings{ 533 Generic: []string{"github.com/jr_hacker/stuff"}, 534 }, 535 Cgo: true, 536 }, 537 }, 538 } 539 checkFiles(t, files, "example.com/repo", want) 540 } 541 542 func TestIgnore(t *testing.T) { 543 files := []fileSpec{ 544 { 545 path: "BUILD", 546 content: "# gazelle:ignore", 547 }, { 548 path: "foo.go", 549 content: "package foo", 550 }, { 551 path: "bar/bar.go", 552 content: "package bar", 553 }, 554 } 555 want := []*packages.Package{ 556 { 557 Name: "bar", 558 Rel: "bar", 559 ImportPath: "example.com/repo/bar", 560 Library: packages.GoTarget{ 561 Sources: packages.PlatformStrings{ 562 Generic: []string{"bar.go"}, 563 }, 564 }, 565 }, 566 } 567 checkFiles(t, files, "example.com/repo", want) 568 } 569 570 func TestExcluded(t *testing.T) { 571 files := []fileSpec{ 572 { 573 path: "BUILD", 574 content: "# gazelle:exclude exclude/do.go", 575 }, { 576 path: "exclude/BUILD", 577 content: ` 578 # gazelle:exclude not.go 579 580 # gazelle:exclude build.go 581 582 genrule( 583 name = "gen_build", 584 outs = ["build.go"], 585 ) 586 `, 587 }, 588 { 589 path: "exclude/do.go", 590 content: "", 591 }, 592 { 593 path: "exclude/not.go", 594 content: "", 595 }, 596 { 597 path: "exclude/build.go", 598 content: "", 599 }, 600 { 601 path: "exclude/real.go", 602 content: "package exclude", 603 }, 604 } 605 want := []*packages.Package{ 606 { 607 Name: "exclude", 608 Rel: "exclude", 609 ImportPath: "example.com/repo/exclude", 610 Library: packages.GoTarget{ 611 Sources: packages.PlatformStrings{ 612 Generic: []string{"real.go"}, 613 }, 614 }, 615 }, 616 } 617 checkFiles(t, files, "example.com/repo", want) 618 } 619 620 func TestExcludedPbGo(t *testing.T) { 621 files := []fileSpec{ 622 { 623 path: "exclude/BUILD", 624 content: ` 625 # gazelle:exclude a.proto 626 `, 627 }, 628 { 629 path: "exclude/a.proto", 630 content: `syntax = "proto2"; 631 package exclude;`, 632 }, 633 { 634 path: "exclude/a.pb.go", 635 content: `package exclude`, 636 }, 637 { 638 path: "exclude/b.proto", 639 content: `syntax = "proto2"; 640 package exclude; 641 `, 642 }, 643 { 644 path: "exclude/b.pb.go", 645 content: `package exclude`, 646 }, 647 } 648 want := []*packages.Package{ 649 { 650 Name: "exclude", 651 Rel: "exclude", 652 ImportPath: "example.com/repo/exclude", 653 Library: packages.GoTarget{ 654 Sources: packages.PlatformStrings{ 655 Generic: []string{"a.pb.go"}, 656 }, 657 }, 658 Proto: packages.ProtoTarget{ 659 Sources: packages.PlatformStrings{ 660 Generic: []string{"b.proto"}, 661 }, 662 HasPbGo: true, 663 }, 664 }, 665 } 666 checkFiles(t, files, "example.com/repo", want) 667 } 668 669 func TestLegacyProtos(t *testing.T) { 670 files := []fileSpec{ 671 { 672 path: "BUILD", 673 content: `# gazelle:proto legacy`, 674 }, { 675 path: "have_pbgo/a.proto", 676 content: `syntax = "proto2"; 677 package have_pbgo;`, 678 }, { 679 path: "have_pbgo/a.pb.go", 680 content: `package have_pbgo`, 681 }, { 682 path: "no_pbgo/b.proto", 683 content: `syntax = "proto2"; 684 package no_pbgo;`, 685 }, { 686 path: "no_pbgo/other.go", 687 content: `package no_pbgo`, 688 }, { 689 path: "proto_only/c.proto", 690 content: `syntax = "proto2"; 691 package proto_only;`, 692 }, 693 } 694 want := []*packages.Package{ 695 { 696 Name: "have_pbgo", 697 Rel: "have_pbgo", 698 ImportPath: "example.com/repo/have_pbgo", 699 Library: packages.GoTarget{ 700 Sources: packages.PlatformStrings{ 701 Generic: []string{"a.pb.go"}, 702 }, 703 }, 704 Proto: packages.ProtoTarget{ 705 Sources: packages.PlatformStrings{ 706 Generic: []string{"a.proto"}, 707 }, 708 HasPbGo: true, 709 }, 710 }, { 711 Name: "no_pbgo", 712 Rel: "no_pbgo", 713 ImportPath: "example.com/repo/no_pbgo", 714 Library: packages.GoTarget{ 715 Sources: packages.PlatformStrings{ 716 Generic: []string{"other.go"}, 717 }, 718 }, 719 Proto: packages.ProtoTarget{ 720 Sources: packages.PlatformStrings{ 721 Generic: []string{"b.proto"}, 722 }, 723 HasPbGo: false, 724 }, 725 }, 726 } 727 checkFiles(t, files, "example.com/repo", want) 728 } 729 730 func TestMalformedBuildFile(t *testing.T) { 731 files := []fileSpec{ 732 {path: "BUILD", content: "????"}, 733 {path: "foo.go", content: "package foo"}, 734 } 735 want := []*packages.Package{} 736 checkFiles(t, files, "example.com/repo", want) 737 } 738 739 func TestMultipleBuildFiles(t *testing.T) { 740 files := []fileSpec{ 741 {path: "BUILD"}, 742 {path: "BUILD.bazel"}, 743 {path: "foo.go", content: "package foo"}, 744 } 745 want := []*packages.Package{} 746 checkFiles(t, files, "example.com/repo", want) 747 } 748 749 func TestMalformedGoFile(t *testing.T) { 750 files := []fileSpec{ 751 {path: "a.go", content: "pakcage foo"}, 752 {path: "b.go", content: "package foo"}, 753 } 754 want := []*packages.Package{ 755 { 756 Name: "foo", 757 ImportPath: "example.com/repo", 758 Library: packages.GoTarget{ 759 Sources: packages.PlatformStrings{ 760 Generic: []string{"a.go", "b.go"}, 761 }, 762 }, 763 }, 764 } 765 checkFiles(t, files, "example.com/repo", want) 766 } 767 768 func TestSymlinksBasic(t *testing.T) { 769 files := []fileSpec{ 770 {path: "root/a.go", content: "package a"}, 771 {path: "root/b", symlink: "../b"}, // symlink outside repo is followed 772 {path: "root/c", symlink: "c"}, // symlink inside repo is not followed. 773 {path: "root/d", symlink: "../b/d"}, // symlink under root/b not followed 774 {path: "root/e", symlink: "../e"}, 775 {path: "c/c.go", symlink: "package c"}, 776 {path: "b/b.go", content: "package b"}, 777 {path: "b/d/d.go", content: "package d"}, 778 {path: "e/loop", symlink: "loop2"}, // symlink loop 779 {path: "e/loop2", symlink: "loop"}, 780 } 781 dir, err := createFiles(files) 782 if err != nil { 783 t.Fatalf("createFiles() failed with %v; want success", err) 784 } 785 want := []*packages.Package{ 786 { 787 Name: "d", 788 Dir: dir + "/root/b/d", 789 Rel: "b/d", 790 ImportPath: "example.com/repo/b/d", 791 Library: packages.GoTarget{ 792 Sources: packages.PlatformStrings{ 793 Generic: []string{"d.go"}, 794 }, 795 }, 796 }, 797 { 798 Name: "b", 799 Dir: dir + "/root/b", 800 Rel: "b", 801 ImportPath: "example.com/repo/b", 802 Library: packages.GoTarget{ 803 Sources: packages.PlatformStrings{ 804 Generic: []string{"b.go"}, 805 }, 806 }, 807 }, 808 { 809 Name: "a", 810 Dir: dir + "/root", 811 ImportPath: "example.com/repo", 812 Library: packages.GoTarget{ 813 Sources: packages.PlatformStrings{ 814 Generic: []string{"a.go"}, 815 }, 816 }, 817 }, 818 } 819 c := &config.Config{ 820 RepoRoot: dir + "/root", 821 GoPrefix: "example.com/repo", 822 Dirs: []string{dir + "/root"}, 823 ValidBuildFileNames: config.DefaultValidBuildFileNames, 824 } 825 got := walkPackages(c) 826 checkPackages(t, got, want) 827 } 828 829 func TestSymlinksIgnore(t *testing.T) { 830 files := []fileSpec{ 831 { 832 path: "root/BUILD", 833 content: "# gazelle:exclude b", 834 }, 835 {path: "root/b", symlink: "../b"}, 836 {path: "b/b.go", content: "package b"}, 837 } 838 dir, err := createFiles(files) 839 if err != nil { 840 t.Fatalf("createFiles() failed with %v; want success", err) 841 } 842 want := []*packages.Package{} 843 c := &config.Config{ 844 RepoRoot: dir + "/root", 845 GoPrefix: "example.com/repo", 846 Dirs: []string{dir + "/root"}, 847 ValidBuildFileNames: config.DefaultValidBuildFileNames, 848 } 849 got := walkPackages(c) 850 checkPackages(t, got, want) 851 } 852 853 func TestSymlinksMixIgnoredAndNonIgnored(t *testing.T) { 854 files := []fileSpec{ 855 { 856 path: "root/BUILD", 857 content: "# gazelle:exclude b", 858 }, 859 {path: "root/b", symlink: "../b"}, // ignored 860 {path: "root/b2", symlink: "../b"}, // not ignored 861 {path: "b/b.go", content: "package b"}, 862 } 863 dir, err := createFiles(files) 864 if err != nil { 865 t.Fatalf("createFiles() failed with %v; want success", err) 866 } 867 want := []*packages.Package{ 868 { 869 Name: "b", 870 Dir: dir + "/root/b2", 871 Rel: "b2", 872 ImportPath: "example.com/repo/b2", 873 Library: packages.GoTarget{ 874 Sources: packages.PlatformStrings{ 875 Generic: []string{"b.go"}, 876 }, 877 }, 878 }, 879 } 880 c := &config.Config{ 881 RepoRoot: dir + "/root", 882 GoPrefix: "example.com/repo", 883 Dirs: []string{dir + "/root"}, 884 ValidBuildFileNames: config.DefaultValidBuildFileNames, 885 } 886 got := walkPackages(c) 887 checkPackages(t, got, want) 888 } 889 890 func TestSymlinksChained(t *testing.T) { 891 files := []fileSpec{ 892 {path: "root/b", symlink: "../link0"}, 893 {path: "link0", symlink: "b"}, 894 {path: "root/b2", symlink: "../b"}, 895 {path: "b/b.go", content: "package b"}, 896 } 897 dir, err := createFiles(files) 898 if err != nil { 899 t.Fatalf("createFiles() failed with %v; want success", err) 900 } 901 want := []*packages.Package{ 902 { 903 Name: "b", 904 Dir: dir + "/root/b", 905 Rel: "b", 906 ImportPath: "example.com/repo/b", 907 Library: packages.GoTarget{ 908 Sources: packages.PlatformStrings{ 909 Generic: []string{"b.go"}, 910 }, 911 }, 912 }, 913 } 914 c := &config.Config{ 915 RepoRoot: dir + "/root", 916 GoPrefix: "example.com/repo", 917 Dirs: []string{dir + "/root"}, 918 ValidBuildFileNames: config.DefaultValidBuildFileNames, 919 } 920 got := walkPackages(c) 921 checkPackages(t, got, want) 922 } 923 924 func TestSymlinksDangling(t *testing.T) { 925 files := []fileSpec{ 926 {path: "root/b", symlink: "../b"}, 927 } 928 dir, err := createFiles(files) 929 if err != nil { 930 t.Fatalf("createFiles() failed with %v; want success", err) 931 } 932 want := []*packages.Package{} 933 c := &config.Config{ 934 RepoRoot: dir + "/root", 935 GoPrefix: "example.com/repo", 936 Dirs: []string{dir + "/root"}, 937 ValidBuildFileNames: config.DefaultValidBuildFileNames, 938 } 939 got := walkPackages(c) 940 checkPackages(t, got, want) 941 }