github.com/bazelbuild/bazel-gazelle@v0.36.1-0.20240520142334-61b277ba6fed/merger/merger_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 merger_test
    17  
    18  import (
    19  	"path/filepath"
    20  	"testing"
    21  
    22  	"github.com/bazelbuild/bazel-gazelle/language"
    23  	golang "github.com/bazelbuild/bazel-gazelle/language/go"
    24  	"github.com/bazelbuild/bazel-gazelle/language/proto"
    25  	"github.com/bazelbuild/bazel-gazelle/merger"
    26  	"github.com/bazelbuild/bazel-gazelle/rule"
    27  )
    28  
    29  // should fix
    30  // * updated srcs from new
    31  // * data and size preserved from old
    32  // * load stmt fixed to those in use and sorted
    33  
    34  type testCase struct {
    35  	desc, previous, current, empty, expected string
    36  }
    37  
    38  var testCases = []testCase{
    39  	{
    40  		desc: "basic functionality",
    41  		previous: `
    42  load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_prefix", "go_test")
    43  
    44  go_prefix("github.com/jr_hacker/tools")
    45  
    46  go_library(
    47      name = "go_default_library",
    48      srcs = [
    49          "lex.go",
    50          "print.go",
    51          "debug.go",
    52      ],
    53  )
    54  
    55  go_test(
    56      name = "go_default_test",
    57      size = "small",
    58      srcs = [
    59          "gen_test.go",  # keep
    60          "parse_test.go",
    61      ],
    62      data = glob(["testdata/*"]),
    63      embed = [":go_default_library"],
    64  )
    65  `,
    66  		current: `
    67  load("@io_bazel_rules_go//go:def.bzl", "go_test", "go_library")
    68  
    69  go_prefix("")
    70  
    71  go_library(
    72      name = "go_default_library",
    73      srcs = [
    74          "lex.go",
    75          "print.go",
    76      ],
    77  )
    78  
    79  go_test(
    80      name = "go_default_test",
    81      srcs = [
    82          "parse_test.go",
    83          "print_test.go",
    84      ],
    85      embed = [":go_default_library"],
    86  )
    87  `,
    88  		expected: `
    89  load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_prefix", "go_test")
    90  
    91  go_prefix("github.com/jr_hacker/tools")
    92  
    93  go_library(
    94      name = "go_default_library",
    95      srcs = [
    96          "lex.go",
    97          "print.go",
    98      ],
    99  )
   100  
   101  go_test(
   102      name = "go_default_test",
   103      size = "small",
   104      srcs = [
   105          "gen_test.go",  # keep
   106          "parse_test.go",
   107          "print_test.go",
   108      ],
   109      data = glob(["testdata/*"]),
   110      embed = [":go_default_library"],
   111  )
   112  `,
   113  	}, {
   114  		desc: "merge dicts",
   115  		previous: `
   116  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   117  
   118  go_library(
   119      name = "go_default_library",
   120      srcs = select({
   121          "darwin_amd64": [
   122              "foo_darwin_amd64.go", # keep
   123              "bar_darwin_amd64.go",
   124          ],
   125          "linux_arm": [
   126              "foo_linux_arm.go", # keep
   127              "bar_linux_arm.go",
   128          ],
   129      }),
   130  )
   131  `,
   132  		current: `
   133  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   134  
   135  go_library(
   136      name = "go_default_library",
   137      srcs = select({
   138          "linux_arm": ["baz_linux_arm.go"],
   139          "darwin_amd64": ["baz_darwin_amd64.go"],
   140          "//conditions:default": [],
   141      }),
   142  )
   143  `,
   144  		expected: `
   145  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   146  
   147  go_library(
   148      name = "go_default_library",
   149      srcs = select({
   150          "darwin_amd64": [
   151              "baz_darwin_amd64.go",
   152              "foo_darwin_amd64.go",  # keep
   153          ],
   154          "linux_arm": [
   155              "baz_linux_arm.go",
   156              "foo_linux_arm.go",  # keep
   157          ],
   158          "//conditions:default": [],
   159      }),
   160  )
   161  `,
   162  	}, {
   163  		desc: "merge old dict with gen list",
   164  		previous: `
   165  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   166  
   167  go_library(
   168      name = "go_default_library",
   169      srcs = select({
   170          "linux_arm": [
   171              "foo_linux_arm.go", # keep
   172              "bar_linux_arm.go", # keep
   173          ],
   174          "darwin_amd64": [
   175              "bar_darwin_amd64.go",
   176          ],
   177      }),
   178  )
   179  `,
   180  		current: `
   181  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   182  
   183  go_library(
   184      name = "go_default_library",
   185      srcs = ["baz.go"],
   186  )
   187  `,
   188  		expected: `
   189  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   190  
   191  go_library(
   192      name = "go_default_library",
   193      srcs = [
   194          "baz.go",
   195      ] + select({
   196          "linux_arm": [
   197              "bar_linux_arm.go",  # keep
   198              "foo_linux_arm.go",  # keep
   199          ],
   200      }),
   201  )
   202  `,
   203  	}, {
   204  		desc: "merge old list with gen dict",
   205  		previous: `
   206  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   207  
   208  go_library(
   209      name = "go_default_library",
   210      srcs = [
   211          "foo.go", # keep
   212          "bar.go", # keep
   213      ],
   214  )
   215  `,
   216  		current: `
   217  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   218  
   219  go_library(
   220      name = "go_default_library",
   221      srcs = select({
   222          "linux_arm": [
   223              "foo_linux_arm.go",
   224              "bar_linux_arm.go",
   225          ],
   226          "darwin_amd64": [
   227              "bar_darwin_amd64.go",
   228          ],
   229          "//conditions:default": [],
   230      }),
   231  )
   232  `,
   233  		expected: `
   234  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   235  
   236  go_library(
   237      name = "go_default_library",
   238      srcs = [
   239          "bar.go",  # keep
   240          "foo.go",  # keep
   241      ] + select({
   242          "linux_arm": [
   243              "bar_linux_arm.go",
   244              "foo_linux_arm.go",
   245          ],
   246          "darwin_amd64": [
   247              "bar_darwin_amd64.go",
   248          ],
   249          "//conditions:default": [],
   250      }),
   251  )
   252  `,
   253  	}, {
   254  		desc: "merge old list and dict with gen list and dict",
   255  		previous: `
   256  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   257  
   258  go_library(
   259      name = "go_default_library",
   260      srcs = [
   261          "foo.go",  # keep
   262          "bar.go",
   263      ] + select({
   264          "linux_arm": [
   265              "foo_linux_arm.go",  # keep
   266          ],
   267          "//conditions:default": [],
   268      }),
   269  )
   270  `,
   271  		current: `
   272  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   273  
   274  go_library(
   275      name = "go_default_library",
   276      srcs = ["baz.go"] + select({
   277          "linux_arm": ["bar_linux_arm.go"],
   278          "darwin_amd64": ["foo_darwin_amd64.go"],
   279          "//conditions:default": [],
   280      }),
   281  )
   282  `,
   283  		expected: `
   284  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   285  
   286  go_library(
   287      name = "go_default_library",
   288      srcs = [
   289          "baz.go",
   290          "foo.go",  # keep
   291      ] + select({
   292          "darwin_amd64": ["foo_darwin_amd64.go"],
   293          "linux_arm": [
   294              "bar_linux_arm.go",
   295              "foo_linux_arm.go",  # keep
   296          ],
   297          "//conditions:default": [],
   298      }),
   299  )
   300  `,
   301  	}, {
   302  		desc: "os and arch",
   303  		previous: `
   304  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   305  
   306  go_library(
   307      name = "go_default_library",
   308      srcs = [
   309          "generic_1.go",
   310      ] + select({
   311          "@io_bazel_rules_go//go/platform:linux": [
   312              "os_linux.go",  # keep
   313          ],
   314          "//conditions:default": [],
   315      }),
   316  )
   317  `,
   318  		current: `
   319  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   320  
   321  go_library(
   322      name = "go_default_library",
   323      srcs = [
   324          "generic_2.go",
   325      ] + select({
   326          "@io_bazel_rules_go//go/platform:amd64": ["arch_amd64.go"],
   327          "//conditions:default": [],
   328      }),
   329  )
   330  `,
   331  		expected: `
   332  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   333  
   334  go_library(
   335      name = "go_default_library",
   336      srcs = [
   337          "generic_2.go",
   338      ] + select({
   339          "@io_bazel_rules_go//go/platform:linux": [
   340              "os_linux.go",  # keep
   341          ],
   342          "//conditions:default": [],
   343      }) + select({
   344          "@io_bazel_rules_go//go/platform:amd64": ["arch_amd64.go"],
   345          "//conditions:default": [],
   346      }),
   347  )
   348  `,
   349  	}, {
   350  		desc: "merge error keeps old",
   351  		previous: `
   352  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   353  
   354  go_library(
   355      name = "go_default_library",
   356      srcs = glob(["*.go"]),
   357  )
   358  `,
   359  		current: `
   360  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   361  
   362  go_library(
   363      name = "go_default_library",
   364      srcs = ["foo.go"],
   365  )
   366  `,
   367  		expected: `
   368  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   369  
   370  go_library(
   371      name = "go_default_library",
   372      srcs = glob(["*.go"]),
   373  )
   374  `,
   375  	}, {
   376  		desc: "delete empty list",
   377  		previous: `
   378  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   379  
   380  go_library(
   381      name = "go_default_library",
   382      srcs = ["deleted.go"],
   383  )
   384  `,
   385  		current: `
   386  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   387  
   388  go_library(
   389      name = "go_default_library",
   390      srcs = select({
   391          "linux_arm": ["foo_linux_arm.go"],
   392      }),
   393  )
   394  `,
   395  		expected: `
   396  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   397  
   398  go_library(
   399      name = "go_default_library",
   400      srcs = select({
   401          "linux_arm": ["foo_linux_arm.go"],
   402      }),
   403  )
   404  `,
   405  	}, {
   406  		desc: "delete empty dict",
   407  		previous: `
   408  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   409  
   410  go_library(
   411      name = "go_default_library",
   412      srcs = select({
   413          "linux_arm": ["foo_linux_arm.go"],
   414          "//conditions:default": [],
   415      }),
   416  )
   417  `,
   418  		current: `
   419  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   420  
   421  go_library(
   422      name = "go_default_library",
   423      srcs = ["foo.go"],
   424  )
   425  `,
   426  		expected: `
   427  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   428  
   429  go_library(
   430      name = "go_default_library",
   431      srcs = ["foo.go"],
   432  )
   433  `,
   434  	}, {
   435  		desc: "delete empty attr",
   436  		previous: `
   437  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   438  
   439  go_library(
   440      name = "go_default_library",
   441      srcs = ["foo.go"],
   442      embed = ["deleted"],
   443  )
   444  `,
   445  		current: `
   446  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   447  
   448  go_library(
   449      name = "go_default_library",
   450      srcs = ["foo.go"],
   451  )
   452  `,
   453  		expected: `
   454  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   455  
   456  go_library(
   457      name = "go_default_library",
   458      srcs = ["foo.go"],
   459  )
   460  `,
   461  	}, {
   462  		desc: "delete empty lists",
   463  		previous: `
   464  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   465  
   466  go_library(
   467      name = "go_default_library",
   468      srcs = ["foo.go"],
   469      embed = ["deleted"],
   470  )
   471  `,
   472  		current: `
   473  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   474  
   475  go_library(
   476      name = "go_default_library",
   477      srcs = ["foo.go"],
   478      embed = [],
   479  )
   480  `,
   481  		expected: `
   482  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   483  
   484  go_library(
   485      name = "go_default_library",
   486      srcs = ["foo.go"],
   487  )
   488  `,
   489  	}, {
   490  		desc: "merge comments",
   491  		previous: `
   492  # load
   493  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   494  
   495  # rule
   496  go_library(
   497      # unmerged attr
   498      name = "go_default_library",
   499      # merged attr
   500      srcs = ["foo.go"],
   501  )
   502  `,
   503  		current: `
   504  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   505  
   506  go_library(
   507      name = "go_default_library",
   508      srcs = ["foo.go"],
   509  )
   510  `,
   511  		expected: `
   512  # load
   513  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   514  
   515  # rule
   516  go_library(
   517      # unmerged attr
   518      name = "go_default_library",
   519      # merged attr
   520      srcs = ["foo.go"],
   521  )
   522  `,
   523  	}, {
   524  		desc: "preserve comments",
   525  		previous: `
   526  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   527  
   528  go_library(
   529      name = "go_default_library",
   530      srcs = [
   531          "a.go",  # preserve
   532          "b.go",  # comments
   533      ],
   534  )
   535  `,
   536  		current: `
   537  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   538  
   539  go_library(
   540      name = "go_default_library",
   541      srcs = ["a.go", "b.go"],
   542  )
   543  `,
   544  		expected: `
   545  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   546  
   547  go_library(
   548      name = "go_default_library",
   549      srcs = [
   550          "a.go",  # preserve
   551          "b.go",  # comments
   552      ],
   553  )
   554  `,
   555  	}, {
   556  		desc: "merge copts and clinkopts",
   557  		previous: `
   558  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   559  
   560  go_library(
   561      name = "cgo_default_library",
   562      copts = [
   563          "-O0",
   564          "-g",  # keep
   565      ],
   566      clinkopts = [
   567          "-lX11",
   568      ],
   569  )
   570  `,
   571  		current: `
   572  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   573  
   574  go_library(
   575      name = "cgo_default_library",
   576      cgo = True,
   577      copts = [
   578          "-O2",
   579      ],
   580      clinkopts = [
   581          "-lpng",
   582      ],
   583  )
   584  `,
   585  		expected: `
   586  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   587  
   588  go_library(
   589      name = "cgo_default_library",
   590      cgo = True,
   591      clinkopts = [
   592          "-lpng",
   593      ],
   594      copts = [
   595          "-g",  # keep
   596          "-O2",
   597      ],
   598  )
   599  `,
   600  	}, {
   601  		desc: "keep scalar attr",
   602  		previous: `
   603  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   604  
   605  go_library(
   606      name = "go_default_library",
   607      embed = [":lib"],  # keep
   608  )
   609  `,
   610  		current: `
   611  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   612  
   613  go_library(
   614      name = "go_default_library",
   615  )
   616  `,
   617  		expected: `
   618  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   619  
   620  go_library(
   621      name = "go_default_library",
   622      embed = [":lib"],  # keep
   623  )
   624  `,
   625  	}, {
   626  		desc: "don't delete list with keep",
   627  		previous: `
   628  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   629  
   630  go_library(
   631      name = "go_default_library",
   632      srcs = [
   633          "one.go",  # keep
   634      ],
   635  )
   636  `,
   637  		current: `
   638  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   639  
   640  go_library(
   641      name = "go_default_library",
   642  )
   643  `,
   644  		expected: `
   645  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   646  
   647  go_library(
   648      name = "go_default_library",
   649      srcs = [
   650          "one.go",  # keep
   651      ],
   652  )
   653  `,
   654  	}, {
   655  		desc: "keep list multiline",
   656  		previous: `
   657  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   658  
   659  go_library(
   660      name = "go_default_library",
   661      srcs = [
   662          "one.go",  # keep
   663          "two.go",
   664      ],
   665  )
   666  `,
   667  		current: `
   668  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   669  
   670  go_library(
   671      name = "go_default_library",
   672  )
   673  `,
   674  		expected: `
   675  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   676  
   677  go_library(
   678      name = "go_default_library",
   679      srcs = [
   680          "one.go",  # keep
   681      ],
   682  )
   683  `,
   684  	}, {
   685  		desc: "keep dict list multiline",
   686  		previous: `
   687  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   688  
   689  go_library(
   690      name = "go_default_library",
   691      srcs = select({
   692          "darwin_amd64": [
   693              "one_darwin.go",  # keep
   694          ],
   695          "linux_arm": [
   696              "one_linux.go",  # keep
   697              "two_linux.go",
   698          ],
   699      }),
   700  )
   701  `,
   702  		current: `
   703  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   704  
   705  go_library(
   706      name = "go_default_library",
   707  )
   708  `,
   709  		expected: `
   710  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   711  
   712  go_library(
   713      name = "go_default_library",
   714      srcs = select({
   715          "darwin_amd64": [
   716              "one_darwin.go",  # keep
   717          ],
   718          "linux_arm": [
   719              "one_linux.go",  # keep
   720          ],
   721      }),
   722  )
   723  `,
   724  	}, {
   725  		desc: "keep prevents delete",
   726  		previous: `
   727  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   728  
   729  # keep
   730  go_library(
   731      name = "go_default_library",
   732      srcs = ["lib.go"],
   733  )
   734  `,
   735  		empty: `
   736  go_library(name = "go_default_library")
   737  `,
   738  		expected: `
   739  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   740  
   741  # keep
   742  go_library(
   743      name = "go_default_library",
   744      srcs = ["lib.go"],
   745  )
   746  `,
   747  	}, {
   748  		desc: "keep prevents merge",
   749  		previous: `
   750  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   751  
   752  # keep
   753  go_library(
   754      name = "go_default_library",
   755      srcs = ["old.go"],
   756  )
   757  `,
   758  		current: `
   759  go_library(
   760      name = "go_default_library",
   761      srcs = ["new.go"],
   762  )
   763  `,
   764  		expected: `
   765  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   766  
   767  # keep
   768  go_library(
   769      name = "go_default_library",
   770      srcs = ["old.go"],
   771  )
   772  `,
   773  	}, {
   774  		desc: "delete empty rule",
   775  		previous: `
   776  load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
   777  
   778  go_library(
   779      name = "go_default_library",
   780      srcs = ["lib.go"],
   781  )
   782  
   783  go_binary(
   784      name = "old",
   785      srcs = ["bin.go"],
   786      embed = [":go_default_library"],
   787      importpath = "foo",
   788  )
   789  `,
   790  		current: `
   791  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   792  
   793  go_library(
   794      name = "go_default_library",
   795      srcs = ["lib.go"],
   796  )
   797  `,
   798  		empty: `
   799  go_binary(name = "old")
   800  `,
   801  		expected: `
   802  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   803  
   804  go_library(
   805      name = "go_default_library",
   806      srcs = ["lib.go"],
   807  )
   808  `,
   809  	}, {
   810  		desc: "don't delete kept rule",
   811  		previous: `
   812  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   813  
   814  go_library(
   815      name = "go_default_library",
   816      srcs = [
   817          "lib.go",  # keep
   818      ],
   819  )
   820  `,
   821  		empty: `go_library(name = "go_default_library")`,
   822  		expected: `
   823  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   824  
   825  go_library(
   826      name = "go_default_library",
   827      srcs = [
   828          "lib.go",  # keep
   829      ],
   830  )
   831  `,
   832  	}, {
   833  		desc: "match and rename",
   834  		previous: `
   835  load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
   836  load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
   837  
   838  go_binary(
   839      name = "custom_bin",
   840      embed = [":custom_library"],
   841  )
   842  
   843  go_library(
   844      name = "custom_library",
   845      embed = [":custom_proto_library"],
   846      importpath = "example.com/repo/foo",
   847  )
   848  
   849  go_proto_library(
   850      name = "custom_proto_library",
   851      importpath = "example.com/repo/foo",
   852      proto = ":foo_proto",
   853  )
   854  `,
   855  		current: `
   856  go_binary(
   857      name = "bin",
   858      srcs = ["bin.go"],
   859      embed = [":go_default_library"],
   860  )
   861  
   862  go_library(
   863      name = "go_default_library",
   864      srcs = ["lib.go"],
   865      embed = [":foo_proto_library"],
   866      importpath = "example.com/repo/foo",
   867  )
   868  
   869  go_proto_library(
   870      name = "foo_proto_library",
   871      importpath = "example.com/repo/foo",
   872      proto = ":foo_proto",
   873  )
   874  `,
   875  		expected: `
   876  load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
   877  load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
   878  
   879  go_binary(
   880      name = "custom_bin",
   881      srcs = ["bin.go"],
   882      embed = [":custom_library"],
   883  )
   884  
   885  go_library(
   886      name = "custom_library",
   887      srcs = ["lib.go"],
   888      embed = [":custom_proto_library"],
   889      importpath = "example.com/repo/foo",
   890  )
   891  
   892  go_proto_library(
   893      name = "custom_proto_library",
   894      importpath = "example.com/repo/foo",
   895      proto = ":foo_proto",
   896  )
   897  `,
   898  	}, {
   899  		desc: "struct macro",
   900  		previous: `load("@bazel_skylib//lib:selects.bzl", "selects")
   901  
   902  selects.config_setting_group(
   903      name = "a",
   904      match_any = [
   905          "//:config_a",
   906          "//:config_b",
   907      ],
   908  )
   909  `,
   910  		current: `load("@bazel_skylib//lib:selects.bzl", "selects")
   911  
   912  selects.config_setting_group(
   913      name = "a",
   914      match_any = [
   915          "//:config_c",
   916          "//:config_d",
   917      ],
   918  )
   919  `,
   920  		expected: `load("@bazel_skylib//lib:selects.bzl", "selects")
   921  
   922  selects.config_setting_group(
   923      name = "a",
   924      match_any = [
   925          "//:config_c",
   926          "//:config_d",
   927      ],
   928  )
   929  `,
   930  	},
   931  }
   932  
   933  func TestMergeFile(t *testing.T) {
   934  	for _, tc := range testCases {
   935  		t.Run(tc.desc, func(t *testing.T) {
   936  			genFile, err := rule.LoadData(filepath.Join("current", "BUILD.bazel"), "", []byte(tc.current))
   937  			if err != nil {
   938  				t.Fatalf("%s: %v", tc.desc, err)
   939  			}
   940  			f, err := rule.LoadData(filepath.Join("previous", "BUILD.bazel"), "", []byte(tc.previous))
   941  			if err != nil {
   942  				t.Fatalf("%s: %v", tc.desc, err)
   943  			}
   944  			emptyFile, err := rule.LoadData(filepath.Join("empty", "BUILD.bazel"), "", []byte(tc.empty))
   945  			if err != nil {
   946  				t.Fatalf("%s: %v", tc.desc, err)
   947  			}
   948  			merger.MergeFile(f, emptyFile.Rules, genFile.Rules, merger.PreResolve, testKinds)
   949  			merger.FixLoads(f, testLoads)
   950  
   951  			want := tc.expected
   952  			if len(want) > 0 && want[0] == '\n' {
   953  				want = want[1:]
   954  			}
   955  
   956  			if got := string(f.Format()); got != want {
   957  				t.Fatalf("%s: got %s; want %s", tc.desc, got, want)
   958  			}
   959  		})
   960  	}
   961  }
   962  
   963  var (
   964  	testKinds map[string]rule.KindInfo
   965  	testLoads []rule.LoadInfo
   966  )
   967  
   968  func init() {
   969  	testKinds = make(map[string]rule.KindInfo)
   970  	langs := []language.Language{proto.NewLanguage(), golang.NewLanguage()}
   971  	for _, lang := range langs {
   972  		for kind, info := range lang.Kinds() {
   973  			testKinds[kind] = info
   974  		}
   975  		loads := lang.(language.ModuleAwareLanguage).ApparentLoads(func(s string) string {
   976  			return ""
   977  		})
   978  		testLoads = append(testLoads, loads...)
   979  	}
   980  
   981  	// add skylib defs
   982  	testLoads = append(testLoads, rule.LoadInfo{
   983  		Name: "@bazel_skylib//lib:selects.bzl",
   984  		Symbols: []string{
   985  			"selects",
   986  		},
   987  	})
   988  
   989  	testKinds["selects.config_setting_group"] = rule.KindInfo{
   990  		MergeableAttrs: map[string]bool{
   991  			"match_all": true,
   992  			"match_any": true,
   993  		},
   994  	}
   995  }
   996  
   997  func TestMatch(t *testing.T) {
   998  	for _, tc := range []struct {
   999  		desc, gen, old string
  1000  		wantIndex      int
  1001  		wantError      bool
  1002  	}{
  1003  		{
  1004  			desc:      "no_match",
  1005  			gen:       `go_library(name = "lib")`,
  1006  			wantIndex: -1,
  1007  		}, {
  1008  			desc:      "name_match",
  1009  			gen:       `go_library(name = "lib")`,
  1010  			old:       `go_library(name = "lib", srcs = ["lib.go"])`,
  1011  			wantIndex: 0,
  1012  		}, {
  1013  			desc:      "name_match_kind_different",
  1014  			gen:       `go_library(name = "lib")`,
  1015  			old:       `cc_library(name = "lib")`,
  1016  			wantError: true,
  1017  		}, {
  1018  			desc:      "attr_match",
  1019  			gen:       `go_library(name = "x", importpath = "foo")`,
  1020  			old:       `go_library(name = "y", importpath = "foo")`,
  1021  			wantIndex: 0,
  1022  		}, {
  1023  			desc: "multiple_attr_match",
  1024  			gen:  `go_library(name = "x", importpath = "foo")`,
  1025  			old: `
  1026  go_library(name = "y", importpath = "foo")
  1027  go_library(name = "z", importpath = "foo")
  1028  `,
  1029  			wantError: true,
  1030  		}, {
  1031  			desc:      "any_match",
  1032  			gen:       `go_binary(name = "x")`,
  1033  			old:       `go_binary(name = "y")`,
  1034  			wantIndex: 0,
  1035  		}, {
  1036  			desc: "multiple_any_match",
  1037  			gen:  `go_binary(name = "x")`,
  1038  			old: `
  1039  go_binary(name = "y")
  1040  go_binary(name = "z")
  1041  `,
  1042  			wantError: true,
  1043  		}, {
  1044  			desc:      "srcs match",
  1045  			gen:       `proto_library(name = "proto1", srcs = ["foo.proto", "bar.proto"])`,
  1046  			old:       `proto_library(name = "proto2", srcs = ["bar.proto", "foo.proto"])`,
  1047  			wantIndex: 0,
  1048  		}, {
  1049  			desc: "importpath match",
  1050  			gen:  `go_proto_library(name = "go_proto1", importpath="example.com/foo")`,
  1051  			old:  `go_proto_library(name = "go_proto2", importpath="example.com/foo")`,
  1052  		}, {
  1053  			desc:      "struct macro match",
  1054  			gen:       `selects.config_setting_group(name = "conf_group_1", match_any = ["//:config_a", "//:config_b"])`,
  1055  			old:       `selects.config_setting_group(name = "conf_group_1", match_any = ["//:config_c", "//:config_d"])`,
  1056  			wantIndex: 0,
  1057  		},
  1058  	} {
  1059  		t.Run(tc.desc, func(t *testing.T) {
  1060  			genFile, err := rule.LoadData(filepath.Join("gen", "BUILD.bazel"), "", []byte(tc.gen))
  1061  			if err != nil {
  1062  				t.Fatal(err)
  1063  			}
  1064  			oldFile, err := rule.LoadData(filepath.Join("old", "BUILD.bazel"), "", []byte(tc.old))
  1065  			if err != nil {
  1066  				t.Fatal(err)
  1067  			}
  1068  			r := genFile.Rules[0]
  1069  			info := testKinds[r.Kind()]
  1070  			if got, gotErr := merger.Match(oldFile.Rules, r, info); gotErr != nil {
  1071  				if !tc.wantError {
  1072  					t.Errorf("unexpected error: %v", gotErr)
  1073  				}
  1074  			} else if tc.wantError {
  1075  				t.Error("unexpected success")
  1076  			} else if got == nil && tc.wantIndex >= 0 {
  1077  				t.Errorf("got nil; want index %d", tc.wantIndex)
  1078  			} else if got != nil && got.Index() != tc.wantIndex {
  1079  				t.Fatalf("got index %d ; want %d", got.Index(), tc.wantIndex)
  1080  			}
  1081  		})
  1082  	}
  1083  }