1#!/usr/bin/env python3 2# Copyright 2017 The Bazel Authors. All rights reserved. 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16from subprocess import check_output, call 17from sys import exit 18from os import path 19 20POPULAR_REPOS = [ 21 dict( 22 name = "org_golang_x_crypto", 23 importpath = "golang.org/x/crypto", 24 urls = "https://codeload.github.com/golang/crypto/zip/5ea612d1eb830b38bc4e914e37f55311eb58adce", 25 strip_prefix = "crypto-5ea612d1eb830b38bc4e914e37f55311eb58adce", 26 type = "zip", 27 excludes = [ 28 "internal/wycheproof:wycheproof_test", # Needs GOROOT 29 "ssh/agent:agent_test", 30 "ssh/test:test_test", 31 "ssh:ssh_test", 32 ], 33 ), 34 35 dict( 36 name = "org_golang_x_net", 37 importpath = "golang.org/x/net", 38 commit = "e18ecbb051101a46fc263334b127c89bc7bff7ea", 39 excludes = [ 40 "bpf:bpf_test", # Needs testdata directory 41 "html/charset:charset_test", # Needs testdata directory 42 "http2:http2_test", # Needs testdata directory 43 "icmp:icmp_test", # icmp requires adjusting kernel options. 44 "internal/socket:socket_test", # Needs GOROOT. 45 "nettest:nettest_test", # 46 "lif:lif_test", 47 ], 48 darwin_tests = [ 49 "route:route_test", # Not supported on linux 50 ] 51 ), 52 53 dict( 54 name = "org_golang_x_sys", 55 importpath = "golang.org/x/sys", 56 commit = "390168757d9c647283340d526204e3409d5903f3", 57 excludes = [ 58 "unix:unix_test", # TestOpenByHandleAt reads source file. 59 "windows:windows_test", # Needs testdata directory 60 ], 61 ), 62 63 dict( 64 name = "org_golang_x_text", 65 importpath = "golang.org/x/text", 66 commit = "e3aa4adf54f644ca0cb35f1f1fb19b239c40ef04", 67 excludes = [ 68 "encoding/charmap:charmap_test", # Needs testdata directory 69 "encoding/japanese:japanese_test", # Needs testdata directory 70 "encoding/korean:korean_test", # Needs testdata directory 71 "encoding/simplifiedchinese:simplifiedchinese_test", # Needs testdata directory 72 "encoding/traditionalchinese:traditionalchinese_test", # Needs testdata directory 73 "encoding/unicode/utf32:utf32_test", # Needs testdata directory 74 "encoding/unicode:unicode_test", # Needs testdata directory 75 "internal/cldrtree:cldrtree_test", # Needs testdata directory 76 "internal/gen/bitfield:bitfield_test", # Needs runfiles 77 "message/pipeline/testdata/test1:test1_test", # Not a real test 78 "message/pipeline:pipeline_test", # Needs testdata directory 79 ], 80 ), 81 82 dict( 83 name = "org_golang_x_tools", 84 importpath = "golang.org/x/tools", 85 commit = "fe37c9e135b934191089b245ac29325091462508", 86 excludes = [ 87 "blog:blog_test", # Needs goldmark 88 "cmd/bundle:bundle_test", # Needs testdata directory 89 "cmd/callgraph/testdata/src/pkg:pkg_test", # is testdata 90 "cmd/callgraph:callgraph_test", # Needs testdata directory 91 "cmd/cover:cover_test", # Needs testdata directory 92 "cmd/file2fuzz:file2fuzz_test", # Requires working GOROOT, uses go build 93 "cmd/fiximports:fiximports_test", # requires working GOROOT, not present in CI. 94 "cmd/godoc:godoc_test", # TODO(#417) 95 "cmd/gorename:gorename_test", # TODO(#417) 96 "cmd/guru/testdata/src/referrers:referrers_test", # Not a real test 97 "cmd/guru:guru_test", # Needs testdata directory 98 "cmd/signature-fuzzer/fuzz-driver:fuzz-driver_test", # requires working GOROOT 99 "cmd/signature-fuzzer/fuzz-runner:fuzz-runner_test", # requires working GOROOT 100 "cmd/signature-fuzzer/internal/fuzz-generator:fuzz-generator_test", # requires working GOROOT 101 "cmd/stringer:stringer_test", # Needs testdata directory 102 "container/intsets:intsets_test", # TODO(#413): External test depends on symbols defined in internal test. 103 "copyright:copyright_test", # # requires runfiles 104 "go/analysis/analysistest:analysistest_test", # requires build cache 105 "go/analysis/internal/analysisflags:analysisflags_test", # calls os.Exit(0) in a test 106 "go/analysis/internal/checker:checker_test", # loads test package with go/packages, which probably needs go list 107 "go/analysis/multichecker:multichecker_test", # requires go vet 108 "go/analysis/passes/asmdecl:asmdecl_test", # Needs testdata directory 109 "go/analysis/passes/assign:assign_test", # Needs testdata directory 110 "go/analysis/passes/atomic:atomic_test", # Needs testdata directory 111 "go/analysis/passes/atomicalign:atomicalign_test", # requires go list 112 "go/analysis/passes/bools:bools_test", # Needs testdata directory 113 "go/analysis/passes/buildssa:buildssa_test", # Needs testdata directory 114 "go/analysis/passes/buildtag:buildtag_test", # Needs testdata directory 115 "go/analysis/passes/cgocall:cgocall_test", # Needs testdata directory 116 "go/analysis/passes/composite:composite_test", # Needs testdata directory 117 "go/analysis/passes/composite/testdata/src/a:a_test", # Does not compile 118 "go/analysis/passes/copylock:copylock_test", # Needs testdata directory 119 "go/analysis/passes/ctrlflow:ctrlflow_test", # Needs testdata directory 120 "go/analysis/passes/deepequalerrors:deepequalerrors_test", # requires go list 121 "go/analysis/passes/errorsas:errorsas_test", # requires go list and testdata 122 "go/analysis/passes/fieldalignment:fieldalignment_test", # Needs GOROOT 123 "go/analysis/passes/findcall:findcall_test", # requires build cache 124 "go/analysis/passes/framepointer:framepointer_test", # Needs GOROOT 125 "go/analysis/passes/httpresponse:httpresponse_test", # Needs testdata directory 126 "go/analysis/passes/ifaceassert:ifaceassert_test", # Needs GOROOT 127 "go/analysis/passes/loopclosure:loopclosure_test", # Needs testdata directory 128 "go/analysis/passes/lostcancel:lostcancel_test", # Needs testdata directory 129 "go/analysis/passes/nilfunc:nilfunc_test", # Needs testdata directory 130 "go/analysis/passes/nilness:nilness_test", # Needs testdata directory 131 "go/analysis/passes/pkgfact:pkgfact_test", # requires go list 132 "go/analysis/passes/printf:printf_test", # Needs testdata directory 133 "go/analysis/passes/reflectvaluecompare:reflectvaluecompare_test", # Needs testdata directory 134 "go/analysis/passes/shadow:shadow_test", # Needs testdata directory 135 "go/analysis/passes/shift:shift_test", # Needs testdata director 136 "go/analysis/passes/sigchanyzer:sigchanyzer_test", # Needs testdata directory 137 "go/analysis/passes/sortslice:sortslice_test", # Needs 'go list' 138 "go/analysis/passes/stdmethods:stdmethods_test", # Needs testdata directory 139 "go/analysis/passes/stringintconv:stringintconv_test", # Needs 'go list' 140 "go/analysis/passes/structtag:structtag_test", # Needs testdata directory 141 "go/analysis/passes/testinggoroutine:testinggoroutine_test", # Need 'go env' 142 "go/analysis/passes/tests/testdata/src/a:a_test", # Not a real test 143 "go/analysis/passes/tests/testdata/src/b_x_test:b_x_test_test", # Not a real test 144 "go/analysis/passes/tests/testdata/src/divergent:divergent_test", # Not a real test 145 "go/analysis/passes/tests/testdata/src/typeparams:typeparams_test", # Not a real test 146 "go/analysis/passes/tests:tests_test", # Needs testdata directory 147 "go/analysis/passes/unmarshal:unmarshal_test", # Needs go list 148 "go/analysis/passes/unreachable:unreachable_test", # Needs testdata directory 149 "go/analysis/passes/unsafeptr:unsafeptr_test", # Needs testdata directory 150 "go/analysis/passes/unusedresult:unusedresult_test", # Needs testdata directory 151 "go/analysis/passes/unusedwrite:unusedwrite_test", # Needs testdata directory 152 "go/analysis/passes/timeformat:timeformat_test", # Needs go tool 153 "go/analysis/passes/usesgenerics:usesgenerics_test", # Needs go tool 154 "go/analysis/unitchecker:unitchecker_test", # requires go vet 155 "go/ast/inspector:inspector_test", # requires GOROOT and GOPATH 156 "go/buildutil:buildutil_test", # Needs testdata directory 157 "go/callgraph/cha:cha_test", # Needs testdata directory 158 "go/callgraph/rta:rta_test", # Needs testdata directory 159 "go/callgraph/vta:vta_test", # Needs testdata directory 160 "go/expect:expect_test", # Needs testdata directory 161 "go/gccgoexportdata:gccgoexportdata_test", # Needs testdata directory 162 "go/gcexportdata:gcexportdata_test", # Needs testdata directory 163 "go/internal/gccgoimporter:gccgoimporter_test", # Needs testdata directory 164 "go/loader:loader_test", # Needs testdata directory 165 "go/packages/packagestest/testdata/groups/two/primarymod/expect:expect_test", # Is testdata 166 "go/packages/packagestest/testdata:testdata_test", # Is testdata 167 "go/packages/packagestest:packagestest_test", # requires build cache 168 "go/packages:packages_test", # Hah! 169 "go/pointer:pointer_test", # Needs testdata directory 170 "go/ssa/interp:interp_test", # Needs testdata directory 171 "go/ssa/ssautil:ssautil_test", # Needs testdata directory 172 "go/ssa:ssa_test", # Needs testdata directory 173 "go/types/typeutil:typeutil_test", # requires GOROOT 174 "go/types/objectpath:objectpath_test", # Incomaptible with Go SDK 1.18.3. Fixed in master but not yet released. TODO: fixme 175 "godoc/static:static_test", # requires data files 176 "godoc/vfs/zipfs:zipfs_test", # requires GOROOT 177 "godoc:godoc_test", # requires GOROOT and GOPATH 178 "internal/apidiff:apidiff_test", # Needs testdata directory 179 "internal/diff/difftest:difftest_test", # Needs diff tool 180 "internal/facts:facts_test", # loads test package with go/packages, which probably needs go list 181 "internal/gcimporter:gcimporter_test", # Needs testdata directory 182 "internal/gocommand:gocommand_test", # Needs go tool 183 "internal/imports:imports_test", # Needs testdata directory 184 "internal/typeparams:typeparams_test", # Needs go tool 185 "present:present_test", # Needs goldmark 186 "refactor/eg:eg_test", # Needs testdata directory 187 "refactor/importgraph:importgraph_test", # TODO(#417) 188 "refactor/rename:rename_test", # TODO(#417) 189 ], 190 ), 191 192 dict( 193 name = "com_github_golang_glog", 194 importpath = "github.com/golang/glog", 195 commit = "23def4e6c14b4da8ac2ed8007337bc5eb5007998", 196 ), 197 198 dict( 199 name = "org_golang_x_sync", 200 importpath = "golang.org/x/sync", 201 commit = "036812b2e83c0ddf193dd5a34e034151da389d09", 202 ), 203 204 dict( 205 name = "org_golang_x_mod", 206 importpath = "golang.org/x/mod", 207 commit = "86c51ed26bb44749b7d60a57bab0e7524656fe8a", 208 excludes = [ 209 "sumdb/tlog:tlog_test", # Needs network, not available on RBE 210 "zip:zip_test", # Needs vcs tools, not available on RBE 211 ], 212 ), 213 ] 214 215COPYRIGHT_HEADER = """ 216# Copyright 2017 The Bazel Authors. All rights reserved. 217# 218# Licensed under the Apache License, Version 2.0 (the "License"); 219# you may not use this file except in compliance with the License. 220# You may obtain a copy of the License at 221# 222# http://www.apache.org/licenses/LICENSE-2.0 223# 224# Unless required by applicable law or agreed to in writing, software 225# distributed under the License is distributed on an "AS IS" BASIS, 226# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 227# See the License for the specific language governing permissions and 228# limitations under the License. 229 230############################## 231# Generated file, do not edit! 232############################## 233""".strip() 234 235BZL_HEADER = COPYRIGHT_HEADER + """ 236 237load("@bazel_gazelle//:def.bzl", "go_repository") 238 239def _maybe(repo_rule, name, **kwargs): 240 if name not in native.existing_rules(): 241 repo_rule(name = name, **kwargs) 242 243def popular_repos(): 244""" 245 246BUILD_HEADER = COPYRIGHT_HEADER 247 248DOCUMENTATION_HEADER = """ 249Popular repository tests 250======================== 251 252These tests are designed to check that gazelle and rules_go together can cope 253with a list of popluar repositories people depend on. 254 255It helps catch changes that might break a large number of users. 256 257.. contents:: 258 259""".lstrip() 260 261LOAD_BAZEL_TEST_RULE = """ 262load("@bazel_skylib//rules:build_test.bzl", "build_test") 263""" 264 265def popular_repos_bzl(): 266 with open(path.join(path.dirname(__file__), "popular_repos.bzl"), "w") as f: 267 f.write(BZL_HEADER) 268 for repo in POPULAR_REPOS: 269 f.write(" _maybe(\n go_repository,\n") 270 for k in ["name", "importpath", "commit", "strip_prefix", "type", "build_file_proto_mode"]: 271 if k in repo: f.write(' {} = "{}",\n'.format(k, repo[k])) 272 for k in ["urls"]: 273 if k in repo: f.write(' {} = ["{}"],\n'.format(k, repo[k])) 274 f.write(" )\n") 275 276def build_bazel(): 277 with open(path.join(path.dirname(__file__), "BUILD.bazel"), "w") as f: 278 f.write(BUILD_HEADER) 279 f.write("\n" + LOAD_BAZEL_TEST_RULE) 280 build_only = [] 281 for repo in POPULAR_REPOS: 282 name = repo["name"] 283 tests = check_output(["bazel", "query", "kind(go_test, \"@{}//...\")".format(name)], text=True).split("\n") 284 excludes = ["@{}//{}".format(name, l) for l in repo.get("excludes", [])] 285 for k in repo: 286 if k.endswith("_excludes") or k.endswith("_tests"): 287 excludes.extend(["@{}//{}".format(name, l) for l in repo[k]]) 288 invalid_excludes = [t for t in excludes if not t in tests] 289 if invalid_excludes: 290 exit("Invalid excludes found: {}".format(invalid_excludes)) 291 build_only.extend(excludes) 292 f.write('\ntest_suite(\n') 293 f.write(' name = "{}",\n'.format(name)) 294 f.write(' tests = [\n') 295 actual = [] 296 for test in sorted(tests, key=lambda test: test.replace(":", "!")): 297 if test in excludes or not test: continue 298 f.write(' "{}",\n'.format(test)) 299 actual.append(test) 300 f.write(' ],\n') 301 #TODO: add in the platform "select" tests 302 f.write(')\n') 303 repo["actual"] = actual 304 305 # add bazel test rule 306 f.write('\nbuild_test(\n') 307 f.write(' name = "{}",\n'.format("build_only")) 308 f.write(' targets = [\n') 309 for package in build_only: 310 if "/internal/" not in package and "/testdata/" not in package: 311 if package.endswith("_test"): 312 f.write(' "{}",\n'.format(package[:-5])) 313 else: 314 f.write(' "{}",\n'.format(package)) 315 f.write(' ],\n') 316 f.write(')\n') 317 318def readme_rst(): 319 with open(path.join(path.dirname(__file__), "README.rst"), "w") as f: 320 f.write(DOCUMENTATION_HEADER) 321 for repo in POPULAR_REPOS: 322 name = repo["name"] 323 f.write("{}\n{}\n\n".format(name, "_"*len(name))) 324 f.write("This runs tests from the repository `{0} <https://{0}>`_\n\n".format(repo["importpath"])) 325 for test in repo["actual"]: 326 f.write("* {}\n".format(test)) 327 f.write("\n\n") 328 329 330def main(): 331 popular_repos_bzl() 332 build_bazel() 333 readme_rst() 334 335if __name__ == "__main__": 336 main() 337