Merge pull request #14 from BenTheElder/clean-old-hacks

clean up development tools / scripts
This commit is contained in:
k8s-ci-robot
2018-09-19 13:49:31 -07:00
committed by GitHub
197 changed files with 143 additions and 23463 deletions

View File

@@ -1,41 +0,0 @@
# gazelle:prefix sigs.k8s.io/kind
# gazelle:proto disable_global
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
go_library(
name = "go_default_library",
srcs = ["main.go"],
importpath = "sigs.k8s.io/kind",
visibility = ["//visibility:public"],
deps = ["//cmd/kind:go_default_library"],
)
go_binary(
name = "kind",
embed = [":go_default_library"],
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"], exclude=["bazel-*/**", ".git/**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//cmd/kind:all-srcs",
"//hack:all-srcs",
"//images:all-srcs",
"//pkg/build:all-srcs",
"//pkg/cluster:all-srcs",
"//pkg/exec:all-srcs",
"//pkg/fs:all-srcs",
"//vendor:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

55
Gopkg.lock generated
View File

@@ -25,40 +25,6 @@
revision = "1a2de0c21c94309923825da3df33a4381872c795"
version = "v1.0.0"
[[projects]]
digest = "1:d7cf27a3bb11248b8d6edc6b65d54cf9ef53bef9d3876e6dce63ce6adc77206b"
name = "github.com/bazelbuild/bazel-gazelle"
packages = [
"cmd/gazelle",
"internal/config",
"internal/flag",
"internal/label",
"internal/language",
"internal/language/go",
"internal/language/proto",
"internal/merger",
"internal/pathtools",
"internal/repos",
"internal/resolve",
"internal/rule",
"internal/version",
"internal/walk",
"internal/wspace",
]
pruneopts = "NUT"
revision = "6a1b93cc9b1c7e55e7d05a6d324bcf9d87ea3ab1"
version = "0.14.0"
[[projects]]
digest = "1:03679414789b10f815a33667d29e3c77e57c8096bd32457fd1682a4222f25806"
name = "github.com/bazelbuild/buildtools"
packages = [
"build",
"tables",
]
pruneopts = "NUT"
revision = "80c7f0d45d7e40fa1f7362852697d4a03df557b3"
[[projects]]
digest = "1:a12d94258c5298ead75e142e8001224bf029f302fed9e96cd39c0eaf90f3954d"
name = "github.com/boltdb/bolt"
@@ -102,14 +68,6 @@
revision = "224a564abe296670b692fe08bb63a3e4c4ad7978"
version = "v0.5.0"
[[projects]]
branch = "master"
digest = "1:e2b86e41f3d669fc36b50d31d32d22c8ac656c75aa5ea89717ce7177e134ff2a"
name = "github.com/golang/glog"
packages = ["."]
pruneopts = "NUT"
revision = "23def4e6c14b4da8ac2ed8007337bc5eb5007998"
[[projects]]
branch = "master"
digest = "1:4ee452f8994700dcab9e816aef1cb9eb2317218734c6ccf5135746e6c19f3dce"
@@ -152,14 +110,6 @@
pruneopts = "NUT"
revision = "6025e8de665b31fa74ab1a66f2cddd8c0abf887e"
[[projects]]
branch = "master"
digest = "1:f60b33d29fc000402656efc11c760f3881d5360a28a47021649f32e770e4b064"
name = "github.com/kubernetes/repo-infra"
packages = ["kazel"]
pruneopts = "NUT"
revision = "84d52408a061e87d45aebf5a0867246bdf66d180"
[[projects]]
branch = "master"
digest = "1:26217ee135b8157549e648efe97dff3282e4bd597a912d784db964df41067f29"
@@ -261,14 +211,13 @@
[[projects]]
branch = "master"
digest = "1:2c7feb35897066f58ae261bfed23e82fa8dba5bc8dfedfca0af8c1af2fcdecb5"
digest = "1:3d35f43f18787f661e7a4c8d8bcd424e96b046ef63769f02ae23e34aa57ff661"
name = "golang.org/x/tools"
packages = [
"go/ast/astutil",
"go/gcexportdata",
"go/internal/gcimporter",
"go/types/typeutil",
"go/vcs",
]
pruneopts = "NUT"
revision = "677d2ff680c188ddb7dcd2bfa6bc7d3f2f2f75b2"
@@ -285,12 +234,10 @@
analyzer-name = "dep"
analyzer-version = 1
input-imports = [
"github.com/bazelbuild/bazel-gazelle/cmd/gazelle",
"github.com/ghodss/yaml",
"github.com/golang/dep/cmd/dep",
"github.com/golang/lint/golint",
"github.com/jteeuwen/go-bindata/go-bindata",
"github.com/kubernetes/repo-infra/kazel",
"github.com/pkg/errors",
"github.com/sirupsen/logrus",
"github.com/spf13/cobra",

View File

@@ -1,9 +1,7 @@
# dev-time dependencies
# ensure they aren't pruned
required = [
"github.com/bazelbuild/bazel-gazelle/cmd/gazelle",
"github.com/jteeuwen/go-bindata/go-bindata",
"github.com/kubernetes/repo-infra/kazel",
"github.com/golang/dep/cmd/dep",
"github.com/golang/lint/golint",
]
@@ -21,10 +19,6 @@ required = [
# latest, unlikely to change as go-bindata is no longer maintained
revision = "6025e8de665b31fa74ab1a66f2cddd8c0abf887e"
[[override]]
name = "github.com/bazelbuild/bazel-gazelle"
version = "0.14.0"
[[override]]
name = "github.com/golang/dep"
version = "v0.5.0"

View File

@@ -1,16 +0,0 @@
# bazel workspace, see: https://bazel.build/
# rules for rules go current stable release below
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "io_bazel_rules_go",
sha256 = "97cf62bdef33519412167fd1e4b0810a318a7c234f5f8dc4f53e2da86241c492",
urls = ["https://github.com/bazelbuild/rules_go/releases/download/0.15.3/rules_go-0.15.3.tar.gz"],
)
load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies", "go_register_toolchains")
go_rules_dependencies()
go_register_toolchains()

View File

@@ -1,34 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["kind.go"],
importpath = "sigs.k8s.io/kind/cmd/kind",
visibility = ["//visibility:public"],
deps = [
"//cmd/kind/build:go_default_library",
"//cmd/kind/create:go_default_library",
"//cmd/kind/delete:go_default_library",
"//vendor/github.com/sirupsen/logrus:go_default_library",
"//vendor/github.com/spf13/cobra:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//cmd/kind/build:all-srcs",
"//cmd/kind/create:all-srcs",
"//cmd/kind/delete:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -1,31 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["build.go"],
importpath = "sigs.k8s.io/kind/cmd/kind/build",
visibility = ["//visibility:public"],
deps = [
"//cmd/kind/build/base:go_default_library",
"//cmd/kind/build/node:go_default_library",
"//vendor/github.com/spf13/cobra:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//cmd/kind/build/base:all-srcs",
"//cmd/kind/build/node:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -1,27 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["base.go"],
importpath = "sigs.k8s.io/kind/cmd/kind/build/base",
visibility = ["//visibility:public"],
deps = [
"//pkg/build/base:go_default_library",
"//vendor/github.com/sirupsen/logrus:go_default_library",
"//vendor/github.com/spf13/cobra:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -1,27 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["node.go"],
importpath = "sigs.k8s.io/kind/cmd/kind/build/node",
visibility = ["//visibility:public"],
deps = [
"//pkg/build/node:go_default_library",
"//vendor/github.com/sirupsen/logrus:go_default_library",
"//vendor/github.com/spf13/cobra:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -1,29 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["create.go"],
importpath = "sigs.k8s.io/kind/cmd/kind/create",
visibility = ["//visibility:public"],
deps = [
"//pkg/cluster:go_default_library",
"//pkg/cluster/config:go_default_library",
"//pkg/cluster/config/encoding:go_default_library",
"//vendor/github.com/sirupsen/logrus:go_default_library",
"//vendor/github.com/spf13/cobra:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -1,27 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["delete.go"],
importpath = "sigs.k8s.io/kind/cmd/kind/delete",
visibility = ["//visibility:public"],
deps = [
"//pkg/cluster:go_default_library",
"//vendor/github.com/sirupsen/logrus:go_default_library",
"//vendor/github.com/spf13/cobra:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -1,4 +0,0 @@
{
"GoPrefix": "sigs.k8s.io/kind",
"AddSourcesRules": true
}

View File

@@ -1,13 +0,0 @@
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -1,74 +0,0 @@
# Copyright 2018 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Genrule wrapper around the go-bindata utility.
# forked from https://github.com/kubernetes/kubernetes/blob/master/build/bindata.bzl
# this variant only supports once source dir
# IMPORTANT: Any changes to this rule may also require changes to hack/generate.sh.
def go_bindata(
# these are for bazel
name,
srcs,
outs,
# -prefix flag
prefix,
# the sources to pass to go-bindata
# NOTE: these must be contained in srcs or bazel will not populate them
bindata_srcs,
# label for the file containing the go:generate directive, so we can
# run go-bindata from the containing package / directory
generate_directive_file,
# -mode flag
mode = "0666",
# -nometadata flag
include_metadata = True,
# -pkg flag
pkg = "generated",
# -ignore flag
ignores = [],
**kw):
args = ['-pkg', pkg]
if not include_metadata:
args.append("-nometadata")
if mode:
args.append("-mode=%s" % mode)
for ignore in ignores:
args.extend(["-ignore", "'%s'" % ignore])
if prefix:
args.append("-prefix=%s" % prefix)
native.genrule(
name = name,
srcs = srcs,
outs = outs,
cmd = " ".join([
# save the original working directory (repo root)
# all paths will be relative to this
"ORIG_WD=$$(pwd);",
# cd to the directory containing the go:generate directive,
# since this is what go generate would do
"cd $$(dirname $(location %s));" % (generate_directive_file),
# run go-bindata
"$$ORIG_WD/$(location %s) -o $$ORIG_WD/$@ %s %s" % (
"//vendor/github.com/jteeuwen/go-bindata/go-bindata:go-bindata",
" ".join(args),
bindata_srcs,
),
]),
tools = [
"//vendor/github.com/jteeuwen/go-bindata/go-bindata",
generate_directive_file,
],
**kw
)

View File

@@ -18,26 +18,11 @@
set -o errexit
set -o nounset
set -o pipefail
set -o verbose
# cd to the repo root
REPO_ROOT=$(git rev-parse --show-toplevel)
cd "${REPO_ROOT}"
exit_trap() {
# we _want_ to check the exit code directly
# shellcheck disable=SC2181
if [ "$?" -eq 0 ]; then
echo "Build passed!"
else
echo "Build Failed!"
fi
}
trap exit_trap EXIT
# build go binaries without bazzel
go install .
# build the entire repo with bazel
bazel build //...
# build kind
set -x
go install -v .

View File

@@ -21,7 +21,6 @@
set -o errexit
set -o nounset
set -o pipefail
set -o verbose
# our exit handler (trap)
cleanup() {

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env bash
# Copyright 2017 The Kubernetes Authors.
# Copyright 2018 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -17,9 +17,7 @@
set -o errexit
set -o nounset
set -o pipefail
set -o verbose
REPO_ROOT=$(git rev-parse --show-toplevel)
"${REPO_ROOT}"/hack/update-bazel.sh
"${REPO_ROOT}"/hack/update-gofmt.sh

View File

@@ -1,44 +0,0 @@
#!/usr/bin/env bash
# Copyright 2018 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -o errexit
set -o nounset
set -o pipefail
REPO_ROOT=$(git rev-parse --show-toplevel)
# https://github.com/kubernetes/test-infra/issues/5699#issuecomment-348350792
cd "${REPO_ROOT}"
TMP_GOPATH=$(mktemp -d)
cleanup() {
rm -rf "${TMP_GOPATH}"
}
trap cleanup EXIT
OUTPUT_GOBIN="${REPO_ROOT}/_output/bin"
GOBIN="${OUTPUT_GOBIN}" go install ./vendor/github.com/bazelbuild/bazel-gazelle/cmd/gazelle
GOBIN="${OUTPUT_GOBIN}" go install ./vendor/github.com/kubernetes/repo-infra/kazel
touch "${REPO_ROOT}/vendor/BUILD.bazel"
"${OUTPUT_GOBIN}/gazelle" fix \
-external=vendored \
-mode=fix
"${OUTPUT_GOBIN}/kazel" \
-cfg-path="${REPO_ROOT}/hack/.kazelcfg.json"

View File

@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
# Copyright 2018 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,7 +24,6 @@
set -o nounset
set -o errexit
set -o pipefail
set -o xtrace
# cd to the repo root
REPO_ROOT=$(git rev-parse --show-toplevel)
@@ -33,47 +32,25 @@ cd "${REPO_ROOT}"
# place to stick temp binaries
BINDIR="${REPO_ROOT}/_output/bin"
# obtain dep either from existing bazel build (in case of running in an sh_binary)
# or install it from vendor into BINDIR
# install dep from vendor into $BINDIR
get_dep() {
# look for local bazel built dep first
local dep
dep="$(find bazel-bin/ -type f -name dep | head -n1)"
# if we found dep from bazel, just return that
if [[ -n "${dep}" ]]; then
echo "dep"
return 0
fi
# otherwise build dep from vendor and use that ...
GOBIN="${BINDIR}" go install ./vendor/github.com/golang/dep/cmd/dep
echo "${BINDIR}/dep"
# build dep from vendor-fake-gopath and use that ...
GOBIN="${BINDIR}" go install ./vendor/github.com/golang/dep/cmd/dep
echo "${BINDIR}/dep"
}
# select dep binary to use
DEP="${DEP:-$(get_dep)}"
# dep itself has a problematic testdata directory with infinite symlinks which
# makes bazel sad: https://github.com/golang/dep/pull/1412
# dep should probably be removing it, but it doesn't:
# https://github.com/golang/dep/issues/1580
rm -rf vendor/github.com/golang/dep/internal/fs/testdata
# go-bindata does too, and is not maintained ...
rm -rf vendor/github.com/jteeuwen/go-bindata/testdata
# TODO(bentheelder): re-enable once (if?) we're using docker client
# docker has a contrib dir with nothing we use in it, dep will retain only the
# licenses, which includes some GPL, so we manually prune this directory.
# licenses, so we manually prune this directory.
# See https://github.com/kubernetes/steering/issues/57
rm -rf vendor/github.com/docker/docker/contrib
#rm -rf vendor/github.com/docker/docker/contrib
# actually run dep
"${DEP}" ensure -v "$@"
# rm all of the junk again
rm -rf vendor/github.com/golang/dep/internal/fs/testdata
rm -rf vendor/github.com/jteeuwen/go-bindata/testdata
rm -rf vendor/github.com/docker/docker/contrib
# update BUILD since we may have updated vendor/...
hack/update-bazel.sh
echo SUCCESS
# TODO(bentheelder): re-enable once (if?) we're using docker client
# we have to rm it again after dep ensure
#rm -rf vendor/github.com/docker/docker/contrib

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/usr/bin/env bash
# Copyright 2018 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,8 +14,9 @@
# limitations under the License.
# 'go generate's kind, using tools from vendor (go-bindata)
set -o nounset
set -o errexit
set -o pipefail
REPO_ROOT=$(git rev-parse --show-toplevel)
@@ -27,5 +28,5 @@ GOBIN="${OUTPUT_GOBIN}" go install ./vendor/github.com/jteeuwen/go-bindata/go-bi
# go generate (using go-bindata)
# NOTE: go will only take package paths, not absolute directories
PATH="${OUTPUT_GOBIN}:${PATH}" go generate ./...
# gofmt the generated file
# gofmt the tree
find . -path "./vendor" -prune -o -name "*.go" -type f -print0 | xargs -0 gofmt -s -w

View File

@@ -19,4 +19,4 @@ set -o errexit
set -o nounset
set -o pipefail
find . -name "*.go" | grep -v "\/vendor\/" | xargs gofmt -s -w
find . -name "*.go" | grep -v "\\/vendor\\/" | xargs gofmt -s -w

View File

@@ -16,7 +16,6 @@
set -o errexit
set -o nounset
set -o pipefail
set -o verbose
# cd to repo root
REPO_ROOT=$(git rev-parse --show-toplevel)
@@ -26,15 +25,26 @@ cd "${REPO_ROOT}"
res=0
# run all verify scripts
"${REPO_ROOT}"/hack/verify-govet.sh || res=1
"${REPO_ROOT}"/hack/verify-gofmt.sh || res=1
"${REPO_ROOT}"/hack/verify-golint.sh || res=1
"${REPO_ROOT}"/hack/verify-generated.sh || res=1
echo "verifying govet ..."
hack/verify-govet.sh || res=1
cd "${REPO_ROOT}"
# TODO(bentheelder): this script must be last because it doesn't operate in a tempdir ...
"${REPO_ROOT}"/hack/verify-deps.sh || res=1
echo "verifying gofmt ..."
hack/verify-gofmt.sh || res=1
cd "${REPO_ROOT}"
echo "verifying golint ..."
hack/verify-golint.sh || res=1
cd "${REPO_ROOT}"
echo "verifying generated ..."
hack/verify-generated.sh || res=1
cd "${REPO_ROOT}"
echo "verifying deps ..."
hack/verify-deps.sh || res=1
cd "${REPO_ROOT}"
set +o verbose
# exit based on verify scripts
if [[ "${res}" = 0 ]]; then
echo ""

View File

@@ -16,24 +16,35 @@
set -o errexit
set -o nounset
set -o pipefail
set -o verbose
# cd to the repo root
REPO_ROOT=$(git rev-parse --show-toplevel)
cd "${REPO_ROOT}"
# run vendor update script
# TODO(bentheelder): investigate why naive variant that uses a tmpdir copy
# of the repo is 10x slower, fix that and use a tmpdir instead..
hack/update-deps.sh
# place to stick temp binaries
BINDIR="${REPO_ROOT}/_output/bin"
# make sure the tree is clean
status="$(git status -s)"
if [[ -n "${status}" ]]; then
echo "unexpectedly dirty working directory after hack/update-deps.sh"
echo "${status}"
echo ""
echo "please run and commit: hack/update-deps.sh"
exit 1
fi
# install dep from vendor into $BINDIR
get_dep() {
# build dep from vendor-fake-gopath and use that ...
GOBIN="${BINDIR}" go install ./vendor/github.com/golang/dep/cmd/dep
echo "${BINDIR}/dep"
}
# select dep binary to use
DEP="${DEP:-$(get_dep)}"
main() {
# run vendor update script in dry run mode
diff=$("${DEP}" check || true)
if [[ -n "${diff}" ]]; then
echo "Non-zero output from dep check" >&2
echo "" >&2
echo "${diff}" >&2
echo "" >&2
echo "please run hack/update-deps.sh" >&2
exit 1
fi
}
main

View File

@@ -13,25 +13,76 @@
# See the License for the specific language governing permissions and
# limitations under the License.
# script to verify generated files
set -o errexit
set -o nounset
set -o pipefail
set -o xtrace
# cd to the repo root
REPO_ROOT=$(git rev-parse --show-toplevel)
cd "${REPO_ROOT}"
bazel build //pkg/build/base/sources:bindata
BAZEL_GENERATED_BINDATA="bazel-genfiles/pkg/build/base/sources/images_sources.go"
GO_GENERATED_BINDATA="pkg/build/base/sources/images_sources.go"
# place to stick temp binaries
BINDIR="${REPO_ROOT}/_output/bin"
mkdir -p "${BINDIR}"
DIFF="$(diff <(cat "${GO_GENERATED_BINDATA}") <(gofmt -s "${BAZEL_GENERATED_BINDATA}"))"
if [ ! -z "$DIFF" ]; then
echo "${GO_GENERATED_BINDATA} does not match ${BAZEL_GENERATED_BINDATA}"
echo "please run and commit: hack/generate.sh"
echo "if you have changed the generation, please ensure these remain identical"
echo "see: hack/bindata.bzl, pkg/build/sources/BUILD.bazel, pkg/build/sources/generate.go"
exit 1
fi
# TMP_GOPATH is used in make_temp_root
TMP_GOPATH="$(TMPDIR="${BINDIR}" mktemp -d "${BINDIR}/verify-deps.XXXXX")"
# exit trap cleanup for TMP_GOPATH
cleanup() {
if [[ -n "${TMP_GOPATH}" ]]; then
rm -rf "${TMP_GOPATH}"
fi
}
# cp -r without any warnings for symlinks ¯\_(ツ)_/¯
quiet_recursive_cp() {
cp -r "${1}" "${2}" >/dev/null 2>&1
}
# copies repo into a temp root saved to TMP_GOPATH
make_temp_root() {
# make a fake gopath
local fake_root="${TMP_GOPATH}/src/sigs.k8s.io/kind"
mkdir -p "${fake_root}"
export -f quiet_recursive_cp
# we need to copy everything but _output (which is .gitignore anyhow)
find . \
-type d -path "./_output" -prune -o \
-mindepth 1 -maxdepth 1 \
-exec bash -c 'quiet_recursive_cp "${0}" "${1}/${0}"' {} "${fake_root}" \;
}
main() {
trap cleanup EXIT
# copy repo root into tempdir under ./_output
echo "Copying tree into temp root ..."
make_temp_root
local fake_root="${TMP_GOPATH}/src/sigs.k8s.io/kind"
# run generated code update script
echo "Updating generated code in '${fake_root}' ..."
cd "${fake_root}"
GOPATH="${TMP_GOPATH}" PATH="${TMP_GOPATH}/bin:${PATH}" hack/update-generated.sh
# make sure the temp repo has no changes relative to the real repo
echo "Diffing '${REPO_ROOT}' '${fake_root}' ..."
diff=$(diff -Nupr \
-x ".git" \
-x "_output" \
-x "vendor/github.com/jteeuwen/go-bindata/testdata" \
-x "vendor/github.com/golang/dep/internal/fs/testdata/symlinks" \
"${REPO_ROOT}" "${fake_root}" 2>/dev/null || true)
if [[ -n "${diff}" ]]; then
echo "unexpectedly dirty working directory after hack/update-generated.sh" >&2
echo "" >&2
echo "${diff}" >&2
echo "" >&2
echo "please run hack/update-generated.sh" >&2
exit 1
fi
}
main

View File

@@ -22,7 +22,7 @@ REPO_ROOT=$(git rev-parse --show-toplevel)
cd "${REPO_ROOT}"
# check for gofmt diffs
diff=$(find . -name "*.go" | grep -v "\/vendor\/" | xargs gofmt -s -d 2>&1)
diff=$(find . -name "*.go" | grep -v "\\/vendor\\/" | xargs gofmt -s -d 2>&1)
if [[ -n "${diff}" ]]; then
echo "${diff}"
echo

View File

@@ -17,7 +17,6 @@
set -o errexit
set -o nounset
set -o pipefail
set -o verbose
# cd to the repo root
REPO_ROOT=$(git rev-parse --show-toplevel)
@@ -25,21 +24,16 @@ cd "${REPO_ROOT}"
# place to stick temp binaries
BINDIR="${REPO_ROOT}/_output/bin"
mkdir -p "${BINDIR}"
# obtain golint either from existing bazel build (in case of running in an sh_binary)
# or install it from vendor into BINDIR
# TMP_GOPATH is used in get_golint
TMP_GOPATH="$(TMPDIR="${BINDIR}" mktemp -d "${BINDIR}/verify-deps.XXXXX")"
trap 'rm -rf "${TMP_GOPATH}"' EXIT
# install golint from vendor into $BINDIR
get_golint() {
# look for local bazel built dep first
local golint
golint="$(find bazel-bin/ -type f -name golint | head -n1)"
# if we found dep from bazel, just return that
if [[ -n "${golint}" ]]; then
echo "golint"
return 0
fi
# otherwise build dep from vendor and use that ...
GOBIN="${BINDIR}" go install ./vendor/github.com/golang/lint/golint
echo "${BINDIR}/golint"
GOBIN="${BINDIR}" go install ./vendor/github.com/golang/lint/golint
echo "${BINDIR}/golint"
}
# select golint binary to use

View File

@@ -17,7 +17,6 @@
set -o errexit
set -o nounset
set -o pipefail
set -o verbose
# cd to the repo root
REPO_ROOT=$(git rev-parse --show-toplevel)

View File

@@ -1,16 +0,0 @@
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//images/base:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -1,16 +0,0 @@
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//images/base/entrypoint:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -1,28 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
go_library(
name = "go_default_library",
srcs = ["main.go"],
importpath = "sigs.k8s.io/kind/images/base/entrypoint",
visibility = ["//visibility:private"],
)
go_binary(
name = "entrypoint",
embed = [":go_default_library"],
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -1,27 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["doc.go"],
importpath = "sigs.k8s.io/kind/pkg/build",
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//pkg/build/base:all-srcs",
"//pkg/build/kube:all-srcs",
"//pkg/build/node:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -1,31 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["base.go"],
importpath = "sigs.k8s.io/kind/pkg/build/base",
visibility = ["//visibility:public"],
deps = [
"//pkg/build/base/sources:go_default_library",
"//pkg/exec:go_default_library",
"//pkg/fs:go_default_library",
"//vendor/github.com/sirupsen/logrus:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//pkg/build/base/sources:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -1,44 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
load("//hack:bindata.bzl", "go_bindata")
# IMPORTANT: if you make any cahnges here, you must also update hack/generate.sh
go_bindata(
name = "bindata",
srcs = [
"//images:all-srcs",
],
outs = [
"images_sources.go",
],
bindata_srcs = "./../../../../images/...",
generate_directive_file = "generate.go",
ignores = ["(\.*README\.md)|(\.*BUILD\.bazel)"],
include_metadata = False,
mode = "0666",
pkg = "sources",
prefix = "./../../../../",
)
go_library(
name = "go_default_library",
srcs = [
"generate.go",
"images_sources.go",
],
importpath = "sigs.k8s.io/kind/pkg/build/base/sources",
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -1,35 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"aptbits.go",
"bazelbuildbits.go",
"bits.go",
"doc.go",
"dockerbuildbits.go",
"source.go",
"version.go",
],
importpath = "sigs.k8s.io/kind/pkg/build/kube",
visibility = ["//visibility:public"],
deps = [
"//pkg/exec:go_default_library",
"//vendor/github.com/pkg/errors:go_default_library",
"//vendor/github.com/sirupsen/logrus:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -1,29 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["node.go"],
importpath = "sigs.k8s.io/kind/pkg/build/node",
visibility = ["//visibility:public"],
deps = [
"//pkg/build/kube:go_default_library",
"//pkg/exec:go_default_library",
"//pkg/fs:go_default_library",
"//vendor/github.com/pkg/errors:go_default_library",
"//vendor/github.com/sirupsen/logrus:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -1,43 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = [
"cluster.go",
"doc.go",
"node.go",
],
importpath = "sigs.k8s.io/kind/pkg/cluster",
visibility = ["//visibility:public"],
deps = [
"//pkg/cluster/config:go_default_library",
"//pkg/cluster/kubeadm:go_default_library",
"//pkg/exec:go_default_library",
"//vendor/github.com/pkg/errors:go_default_library",
"//vendor/github.com/sirupsen/logrus:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//pkg/cluster/config:all-srcs",
"//pkg/cluster/kubeadm:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
go_test(
name = "go_default_test",
srcs = ["cluster_test.go"],
embed = [":go_default_library"],
)

View File

@@ -1,44 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = [
"any.go",
"convert.go",
"deepcopy.go",
"default.go",
"doc.go",
"errors.go",
"types.go",
"validate.go",
"version.go",
],
importpath = "sigs.k8s.io/kind/pkg/cluster/config",
visibility = ["//visibility:public"],
)
go_test(
name = "go_default_test",
srcs = [
"deepcopy_test.go",
"validate_test.go",
],
embed = [":go_default_library"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//pkg/cluster/config/encoding:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -1,34 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = ["encoding.go"],
importpath = "sigs.k8s.io/kind/pkg/cluster/config/encoding",
visibility = ["//visibility:public"],
deps = [
"//pkg/cluster/config:go_default_library",
"//vendor/github.com/ghodss/yaml:go_default_library",
],
)
go_test(
name = "go_default_test",
srcs = ["encoding_test.go"],
data = glob(["testdata/**"]),
embed = [":go_default_library"],
deps = ["//pkg/cluster/config:go_default_library"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -1,27 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"config.go",
"const.go",
"doc.go",
],
importpath = "sigs.k8s.io/kind/pkg/cluster/kubeadm",
visibility = ["//visibility:public"],
deps = ["//vendor/github.com/pkg/errors:go_default_library"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -1,23 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["exec.go"],
importpath = "sigs.k8s.io/kind/pkg/exec",
visibility = ["//visibility:public"],
deps = ["//vendor/github.com/sirupsen/logrus:go_default_library"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -1,22 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["fs.go"],
importpath = "sigs.k8s.io/kind/pkg/fs",
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

62
vendor/BUILD.bazel vendored
View File

@@ -1,62 +0,0 @@
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//vendor/github.com/Masterminds/semver:all-srcs",
"//vendor/github.com/Masterminds/vcs:all-srcs",
"//vendor/github.com/armon/go-radix:all-srcs",
"//vendor/github.com/bazelbuild/bazel-gazelle/cmd/gazelle:all-srcs",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/config:all-srcs",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/flag:all-srcs",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/label:all-srcs",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/language:all-srcs",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/merger:all-srcs",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/pathtools:all-srcs",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/repos:all-srcs",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/resolve:all-srcs",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/rule:all-srcs",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/version:all-srcs",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/walk:all-srcs",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/wspace:all-srcs",
"//vendor/github.com/bazelbuild/buildtools/build:all-srcs",
"//vendor/github.com/bazelbuild/buildtools/tables:all-srcs",
"//vendor/github.com/boltdb/bolt:all-srcs",
"//vendor/github.com/ghodss/yaml:all-srcs",
"//vendor/github.com/golang/dep:all-srcs",
"//vendor/github.com/golang/glog:all-srcs",
"//vendor/github.com/golang/lint/golint:all-srcs",
"//vendor/github.com/golang/protobuf/proto:all-srcs",
"//vendor/github.com/inconshreveable/mousetrap:all-srcs",
"//vendor/github.com/jmank88/nuts:all-srcs",
"//vendor/github.com/jteeuwen/go-bindata:all-srcs",
"//vendor/github.com/kubernetes/repo-infra/kazel:all-srcs",
"//vendor/github.com/nightlyone/lockfile:all-srcs",
"//vendor/github.com/pelletier/go-toml:all-srcs",
"//vendor/github.com/pkg/errors:all-srcs",
"//vendor/github.com/sdboyer/constext:all-srcs",
"//vendor/github.com/sirupsen/logrus:all-srcs",
"//vendor/github.com/spf13/cobra:all-srcs",
"//vendor/github.com/spf13/pflag:all-srcs",
"//vendor/golang.org/x/crypto/ssh/terminal:all-srcs",
"//vendor/golang.org/x/lint:all-srcs",
"//vendor/golang.org/x/net/context:all-srcs",
"//vendor/golang.org/x/sync/errgroup:all-srcs",
"//vendor/golang.org/x/sys/unix:all-srcs",
"//vendor/golang.org/x/sys/windows:all-srcs",
"//vendor/golang.org/x/tools/go/ast/astutil:all-srcs",
"//vendor/golang.org/x/tools/go/gcexportdata:all-srcs",
"//vendor/golang.org/x/tools/go/internal/gcimporter:all-srcs",
"//vendor/golang.org/x/tools/go/types/typeutil:all-srcs",
"//vendor/golang.org/x/tools/go/vcs:all-srcs",
"//vendor/gopkg.in/yaml.v2:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -1,33 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"collection.go",
"constraints.go",
"doc.go",
"error.go",
"magic.go",
"parse.go",
"range.go",
"union.go",
"version.go",
],
importmap = "sigs.k8s.io/kind/vendor/github.com/Masterminds/semver",
importpath = "github.com/Masterminds/semver",
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -1,32 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"bzr.go",
"errors.go",
"git.go",
"hg.go",
"repo.go",
"svn.go",
"vcs_local_lookup.go",
"vcs_remote_lookup.go",
],
importmap = "sigs.k8s.io/kind/vendor/github.com/Masterminds/vcs",
importpath = "github.com/Masterminds/vcs",
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -1,23 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["radix.go"],
importmap = "sigs.k8s.io/kind/vendor/github.com/armon/go-radix",
importpath = "github.com/armon/go-radix",
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -1,18 +0,0 @@
# This is the official list of authors for copyright purposes.
# Names should be added to this file as:
# Name or Organization <email address>
# The email address is not required for organizations.
Andy Hochhaus <hochhaus@users.noreply.github.com>
Antoine Pelisse <apelisse@gmail.com>
GinFungYJF <645116215@qq.com>
Google Inc.
Improbable Worlds Ltd
Jeff Hodges <jeff@somethingsimilar.com>
John Millikin <jmillikin@gmail.com>
Melinda Lu <melinda@vsco.co>
Peter McAlpine <peter@aoeu.ca>
RS <sayrer@gmail.com>
Rodrigo Queiro <overdrigzed@gmail.com>
Tom Payne <twpayne@gmail.com>
Yuki Yugui Sonoda <yugui@yugui.jp>

View File

@@ -1,29 +0,0 @@
# People who have agreed to one of the CLAs and can contribute patches.
# The AUTHORS file lists the copyright holders; this file
# lists people. For example, Google employees are listed here
# but not in AUTHORS, because Google holds the copyright.
#
# https://developers.google.com/open-source/cla/individual
# https://developers.google.com/open-source/cla/corporate
#
# Names should be added to this file as:
# Name <email address>
Ainsley Escorce-Jones <ains@users.noreply.github.com>
Andy Hochhaus <hochhaus@users.noreply.github.com>
Antoine Pelisse <apelisse@gmail.com>
GinFungYJF <645116215@qq.com>
Ian Cottrell <ian.the.hat@gmail.com>
Jay Conrod <jayconrod@gmail.com>
Jeff Grafton <ixdy@users.noreply.github.com>
Jeff Hodges <jeff@somethingsimilar.com>
John Millikin <jmillikin@gmail.com>
Kristina <k.chodorow@gmail.com>
Melinda Lu <melinda@vsco.co>
Paul Bethe <pbethe@google.com>
Peter McAlpine <peter@aoeu.ca>
Rodrigo Queiro <overdrigzed@gmail.com>
RS <sayrer@gmail.com>
Stefan Sakalik <stefan@improbable.io>
Tom Payne <twpayne@gmail.com>
Yuki Yugui Sonoda <yugui@yugui.jp>

View File

@@ -1,202 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -1,52 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
go_library(
name = "go_default_library",
srcs = [
"diff.go",
"fix.go",
"fix-update.go",
"gazelle.go",
"langs.go",
"print.go",
"update-repos.go",
"version.go",
],
importmap = "sigs.k8s.io/kind/vendor/github.com/bazelbuild/bazel-gazelle/cmd/gazelle",
importpath = "github.com/bazelbuild/bazel-gazelle/cmd/gazelle",
visibility = ["//visibility:private"],
deps = [
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/config:go_default_library",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/flag:go_default_library",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/label:go_default_library",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/language:go_default_library",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/language/go:go_default_library",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/language/proto:go_default_library",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/merger:go_default_library",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/repos:go_default_library",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/resolve:go_default_library",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/rule:go_default_library",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/version:go_default_library",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/walk:go_default_library",
],
)
go_binary(
name = "gazelle",
embed = [":go_default_library"],
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -1,52 +0,0 @@
/* Copyright 2016 The Bazel Authors. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"bytes"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
)
func diffFile(path string, newContents []byte) error {
oldContents, err := ioutil.ReadFile(path)
if err != nil {
oldContents = nil
}
if bytes.Equal(oldContents, newContents) {
return nil
}
f, err := ioutil.TempFile("", filepath.Base(path))
if err != nil {
return err
}
f.Close()
defer os.Remove(f.Name())
if err := ioutil.WriteFile(f.Name(), newContents, 0666); err != nil {
return err
}
cmd := exec.Command("diff", "-u", "--new-file", path, f.Name())
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err = cmd.Run()
if _, ok := err.(*exec.ExitError); ok {
// diff returns non-zero when files are different. This is not an error.
return nil
}
return err
}

View File

@@ -1,398 +0,0 @@
/* Copyright 2017 The Bazel Authors. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"flag"
"fmt"
"io/ioutil"
"log"
"os"
"path/filepath"
"strings"
"github.com/bazelbuild/bazel-gazelle/internal/config"
gzflag "github.com/bazelbuild/bazel-gazelle/internal/flag"
"github.com/bazelbuild/bazel-gazelle/internal/label"
"github.com/bazelbuild/bazel-gazelle/internal/merger"
"github.com/bazelbuild/bazel-gazelle/internal/repos"
"github.com/bazelbuild/bazel-gazelle/internal/resolve"
"github.com/bazelbuild/bazel-gazelle/internal/rule"
"github.com/bazelbuild/bazel-gazelle/internal/walk"
)
// updateConfig holds configuration information needed to run the fix and
// update commands. This includes everything in config.Config, but it also
// includes some additional fields that aren't relevant to other packages.
type updateConfig struct {
emit emitFunc
repos []repos.Repo
}
type emitFunc func(path string, data []byte) error
var modeFromName = map[string]emitFunc{
"print": printFile,
"fix": fixFile,
"diff": diffFile,
}
const updateName = "_update"
func getUpdateConfig(c *config.Config) *updateConfig {
return c.Exts[updateName].(*updateConfig)
}
type updateConfigurer struct {
mode string
}
func (ucr *updateConfigurer) RegisterFlags(fs *flag.FlagSet, cmd string, c *config.Config) {
uc := &updateConfig{}
c.Exts[updateName] = uc
c.ShouldFix = cmd == "fix"
fs.StringVar(&ucr.mode, "mode", "fix", "print: prints all of the updated BUILD files\n\tfix: rewrites all of the BUILD files in place\n\tdiff: computes the rewrite but then just does a diff")
}
func (ucr *updateConfigurer) CheckFlags(fs *flag.FlagSet, c *config.Config) error {
uc := getUpdateConfig(c)
var ok bool
uc.emit, ok = modeFromName[ucr.mode]
if !ok {
return fmt.Errorf("unrecognized emit mode: %q", ucr.mode)
}
c.Dirs = fs.Args()
if len(c.Dirs) == 0 {
c.Dirs = []string{"."}
}
for i := range c.Dirs {
dir, err := filepath.Abs(c.Dirs[i])
if err != nil {
return fmt.Errorf("%s: failed to find absolute path: %v", c.Dirs[i], err)
}
dir, err = filepath.EvalSymlinks(dir)
if err != nil {
return fmt.Errorf("%s: failed to resolve symlinks: %v", c.Dirs[i], err)
}
if !isDescendingDir(dir, c.RepoRoot) {
return fmt.Errorf("dir %q is not a subdirectory of repo root %q", dir, c.RepoRoot)
}
c.Dirs[i] = dir
}
return nil
}
func (ucr *updateConfigurer) KnownDirectives() []string { return nil }
func (ucr *updateConfigurer) Configure(c *config.Config, rel string, f *rule.File) {}
// visitRecord stores information about about a directory visited with
// packages.Walk.
type visitRecord struct {
// pkgRel is the slash-separated path to the visited directory, relative to
// the repository root. "" for the repository root itself.
pkgRel string
// rules is a list of generated Go rules.
rules []*rule.Rule
// empty is a list of empty Go rules that may be deleted.
empty []*rule.Rule
// file is the build file being processed.
file *rule.File
}
type byPkgRel []visitRecord
func (vs byPkgRel) Len() int { return len(vs) }
func (vs byPkgRel) Less(i, j int) bool { return vs[i].pkgRel < vs[j].pkgRel }
func (vs byPkgRel) Swap(i, j int) { vs[i], vs[j] = vs[j], vs[i] }
var genericLoads = []rule.LoadInfo{
{
Name: "@bazel_gazelle//:def.bzl",
Symbols: []string{"gazelle"},
},
}
func runFixUpdate(cmd command, args []string) error {
cexts := make([]config.Configurer, 0, len(languages)+2)
cexts = append(cexts, &config.CommonConfigurer{}, &updateConfigurer{})
kindToResolver := make(map[string]resolve.Resolver)
kinds := make(map[string]rule.KindInfo)
loads := genericLoads
for _, lang := range languages {
cexts = append(cexts, lang)
for kind, info := range lang.Kinds() {
kindToResolver[kind] = lang
kinds[kind] = info
}
loads = append(loads, lang.Loads()...)
}
ruleIndex := resolve.NewRuleIndex(kindToResolver)
c, err := newFixUpdateConfiguration(cmd, args, cexts, loads)
if err != nil {
return err
}
if cmd == fixCmd {
// Only check the version when "fix" is run. Generated build files
// frequently work with older version of rules_go, and we don't want to
// nag too much since there's no way to disable this warning.
checkRulesGoVersion(c.RepoRoot)
}
// Visit all directories in the repository.
var visits []visitRecord
walk.Walk(c, cexts, func(dir, rel string, c *config.Config, update bool, f *rule.File, subdirs, regularFiles, genFiles []string) {
// If this file is ignored or if Gazelle was not asked to update this
// directory, just index the build file and move on.
if !update {
if f != nil {
for _, r := range f.Rules {
ruleIndex.AddRule(c, r, f)
}
}
return
}
// Fix any problems in the file.
if f != nil {
for _, l := range languages {
l.Fix(c, f)
}
}
// Generate rules.
var empty, gen []*rule.Rule
for _, l := range languages {
lempty, lgen := l.GenerateRules(c, dir, rel, f, subdirs, regularFiles, genFiles, empty, gen)
empty = append(empty, lempty...)
gen = append(gen, lgen...)
}
if f == nil && len(gen) == 0 {
return
}
// Insert or merge rules into the build file.
if f == nil {
f = rule.EmptyFile(filepath.Join(dir, c.DefaultBuildFileName()), rel)
for _, r := range gen {
r.Insert(f)
}
} else {
merger.MergeFile(f, empty, gen, merger.PreResolve, kinds)
}
visits = append(visits, visitRecord{
pkgRel: rel,
rules: gen,
empty: empty,
file: f,
})
// Add library rules to the dependency resolution table.
for _, r := range f.Rules {
ruleIndex.AddRule(c, r, f)
}
})
uc := getUpdateConfig(c)
// Finish building the index for dependency resolution.
ruleIndex.Finish()
// Resolve dependencies.
rc := repos.NewRemoteCache(uc.repos)
for _, v := range visits {
for _, r := range v.rules {
from := label.New(c.RepoName, v.pkgRel, r.Name())
kindToResolver[r.Kind()].Resolve(c, ruleIndex, rc, r, from)
}
merger.MergeFile(v.file, v.empty, v.rules, merger.PostResolve, kinds)
}
// Emit merged files.
for _, v := range visits {
merger.FixLoads(v.file, loads)
content := v.file.Format()
outputPath := findOutputPath(c, v.file)
if err := uc.emit(outputPath, content); err != nil {
log.Print(err)
}
}
return nil
}
func newFixUpdateConfiguration(cmd command, args []string, cexts []config.Configurer, loads []rule.LoadInfo) (*config.Config, error) {
c := config.New()
fs := flag.NewFlagSet("gazelle", flag.ContinueOnError)
// Flag will call this on any parse error. Don't print usage unless
// -h or -help were passed explicitly.
fs.Usage = func() {}
var knownImports []string
fs.Var(&gzflag.MultiFlag{Values: &knownImports}, "known_import", "import path for which external resolution is skipped (can specify multiple times)")
for _, cext := range cexts {
cext.RegisterFlags(fs, cmd.String(), c)
}
if err := fs.Parse(args); err != nil {
if err == flag.ErrHelp {
fixUpdateUsage(fs)
return nil, err
}
// flag already prints the error; don't print it again.
log.Fatal("Try -help for more information.")
}
for _, cext := range cexts {
if err := cext.CheckFlags(fs, c); err != nil {
return nil, err
}
}
uc := getUpdateConfig(c)
workspacePath := filepath.Join(c.RepoRoot, "WORKSPACE")
if workspace, err := rule.LoadFile(workspacePath, ""); err != nil {
if !os.IsNotExist(err) {
return nil, err
}
} else {
if err := fixWorkspace(c, workspace, loads); err != nil {
return nil, err
}
c.RepoName = findWorkspaceName(workspace)
uc.repos = repos.ListRepositories(workspace)
}
repoPrefixes := make(map[string]bool)
for _, r := range uc.repos {
repoPrefixes[r.GoPrefix] = true
}
for _, imp := range knownImports {
if repoPrefixes[imp] {
continue
}
repo := repos.Repo{
Name: label.ImportPathToBazelRepoName(imp),
GoPrefix: imp,
}
uc.repos = append(uc.repos, repo)
}
return c, nil
}
func fixUpdateUsage(fs *flag.FlagSet) {
fmt.Fprint(os.Stderr, `usage: gazelle [fix|update] [flags...] [package-dirs...]
The update command creates new build files and update existing BUILD files
when needed.
The fix command also creates and updates build files, and in addition, it may
make potentially breaking updates to usage of rules. For example, it may
delete obsolete rules or rename existing rules.
There are several output modes which can be selected with the -mode flag. The
output mode determines what Gazelle does with updated BUILD files.
fix (default) - write updated BUILD files back to disk.
print - print updated BUILD files to stdout.
diff - diff updated BUILD files against existing files in unified format.
Gazelle accepts a list of paths to Go package directories to process (defaults
to the working directory if none are given). It recursively traverses
subdirectories. All directories must be under the directory specified by
-repo_root; if -repo_root is not given, this is the directory containing the
WORKSPACE file.
FLAGS:
`)
fs.PrintDefaults()
}
func fixWorkspace(c *config.Config, workspace *rule.File, loads []rule.LoadInfo) error {
uc := getUpdateConfig(c)
if !c.ShouldFix {
return nil
}
shouldFix := false
for _, d := range c.Dirs {
if d == c.RepoRoot {
shouldFix = true
}
}
if !shouldFix {
return nil
}
merger.FixWorkspace(workspace)
merger.FixLoads(workspace, loads)
if err := merger.CheckGazelleLoaded(workspace); err != nil {
return err
}
return uc.emit(workspace.Path, workspace.Format())
}
func findWorkspaceName(f *rule.File) string {
for _, r := range f.Rules {
if r.Kind() == "workspace" {
return r.Name()
}
}
return ""
}
func isDescendingDir(dir, root string) bool {
rel, err := filepath.Rel(root, dir)
if err != nil {
return false
}
if rel == "." {
return true
}
return !strings.HasPrefix(rel, "..")
}
func findOutputPath(c *config.Config, f *rule.File) string {
if c.ReadBuildFilesDir == "" && c.WriteBuildFilesDir == "" {
return f.Path
}
baseDir := c.WriteBuildFilesDir
if c.WriteBuildFilesDir == "" {
baseDir = c.RepoRoot
}
outputDir := filepath.Join(baseDir, filepath.FromSlash(f.Pkg))
defaultOutputPath := filepath.Join(outputDir, c.DefaultBuildFileName())
files, err := ioutil.ReadDir(outputDir)
if err != nil {
// Ignore error. Directory probably doesn't exist.
return defaultOutputPath
}
outputPath := rule.MatchBuildFileName(outputDir, c.ValidBuildFileNames, files)
if outputPath == "" {
return defaultOutputPath
}
return outputPath
}

View File

@@ -1,29 +0,0 @@
/* Copyright 2016 The Bazel Authors. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"io/ioutil"
"os"
"path/filepath"
)
func fixFile(path string, data []byte) error {
if err := os.MkdirAll(filepath.Dir(path), 0777); err != nil {
return err
}
return ioutil.WriteFile(path, data, 0666)
}

View File

@@ -1,120 +0,0 @@
/* Copyright 2016 The Bazel Authors. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Command gazelle is a BUILD file generator for Go projects.
// See "gazelle --help" for more details.
package main
import (
"flag"
"fmt"
"log"
"os"
)
type command int
const (
updateCmd command = iota
fixCmd
updateReposCmd
helpCmd
)
var commandFromName = map[string]command{
"fix": fixCmd,
"help": helpCmd,
"update": updateCmd,
"update-repos": updateReposCmd,
}
var nameFromCommand = []string{
// keep in sync with definition above
"update",
"fix",
"update-repos",
"help",
}
func (cmd command) String() string {
return nameFromCommand[cmd]
}
func main() {
log.SetPrefix("gazelle: ")
log.SetFlags(0) // don't print timestamps
if err := run(os.Args[1:]); err != nil {
log.Fatal(err)
}
}
func run(args []string) error {
cmd := updateCmd
if len(args) == 1 && (args[0] == "-h" || args[0] == "-help" || args[0] == "--help") {
cmd = helpCmd
} else if len(args) > 0 {
c, ok := commandFromName[args[0]]
if ok {
cmd = c
args = args[1:]
}
}
switch cmd {
case fixCmd, updateCmd:
return runFixUpdate(cmd, args)
case helpCmd:
return help()
case updateReposCmd:
return updateRepos(args)
default:
log.Panicf("unknown command: %v", cmd)
}
return nil
}
func help() error {
fmt.Fprint(os.Stderr, `usage: gazelle <command> [args...]
Gazelle is a BUILD file generator for Go projects. It can create new BUILD files
for a project that follows "go build" conventions, and it can update BUILD files
if they already exist. It can be invoked directly in a project workspace, or
it can be run on an external dependency during the build as part of the
go_repository rule.
Gazelle may be run with one of the commands below. If no command is given,
Gazelle defaults to "update".
update - Gazelle will create new BUILD files or update existing BUILD files
if needed.
fix - in addition to the changes made in update, Gazelle will make potentially
breaking changes. For example, it may delete obsolete rules or rename
existing rules.
update-repos - updates repository rules in the WORKSPACE file. Run with
-h for details.
help - show this message.
For usage information for a specific command, run the command with the -h flag.
For example:
gazelle update -h
Gazelle is under active delevopment, and its interface may change
without notice.
`)
return flag.ErrHelp
}

View File

@@ -1,27 +0,0 @@
/* Copyright 2018 The Bazel Authors. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"github.com/bazelbuild/bazel-gazelle/internal/language"
"github.com/bazelbuild/bazel-gazelle/internal/language/go"
"github.com/bazelbuild/bazel-gazelle/internal/language/proto"
)
var languages = []language.Language{
proto.New(),
golang.New(),
}

View File

@@ -1,25 +0,0 @@
/* Copyright 2016 The Bazel Authors. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"os"
)
func printFile(_ string, data []byte) error {
_, err := os.Stdout.Write(data)
return err
}

View File

@@ -1,200 +0,0 @@
/* Copyright 2017 The Bazel Authors. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"errors"
"flag"
"fmt"
"os"
"path/filepath"
"sync"
"github.com/bazelbuild/bazel-gazelle/internal/config"
"github.com/bazelbuild/bazel-gazelle/internal/merger"
"github.com/bazelbuild/bazel-gazelle/internal/repos"
"github.com/bazelbuild/bazel-gazelle/internal/rule"
)
type updateReposFn func(c *updateReposConfig, oldFile *rule.File, kinds map[string]rule.KindInfo) error
type updateReposConfig struct {
fn updateReposFn
lockFilename string
importPaths []string
}
const updateReposName = "_update-repos"
func getUpdateReposConfig(c *config.Config) *updateReposConfig {
return c.Exts[updateReposName].(*updateReposConfig)
}
type updateReposConfigurer struct{}
func (_ *updateReposConfigurer) RegisterFlags(fs *flag.FlagSet, cmd string, c *config.Config) {
uc := &updateReposConfig{}
c.Exts[updateReposName] = uc
fs.StringVar(&uc.lockFilename, "from_file", "", "Gazelle will translate repositories listed in this file into repository rules in WORKSPACE. Currently only dep's Gopkg.lock is supported.")
}
func (_ *updateReposConfigurer) CheckFlags(fs *flag.FlagSet, c *config.Config) error {
uc := getUpdateReposConfig(c)
switch {
case uc.lockFilename != "":
if len(fs.Args()) != 0 {
return fmt.Errorf("Got %d positional arguments with -from_file; wanted 0.\nTry -help for more information.", len(fs.Args()))
}
uc.fn = importFromLockFile
default:
if len(fs.Args()) == 0 {
return fmt.Errorf("No repositories specified\nTry -help for more information.")
}
uc.fn = updateImportPaths
uc.importPaths = fs.Args()
}
return nil
}
func (_ *updateReposConfigurer) KnownDirectives() []string { return nil }
func (_ *updateReposConfigurer) Configure(c *config.Config, rel string, f *rule.File) {}
func updateRepos(args []string) error {
cexts := make([]config.Configurer, 0, len(languages)+2)
cexts = append(cexts, &config.CommonConfigurer{}, &updateReposConfigurer{})
kinds := make(map[string]rule.KindInfo)
loads := []rule.LoadInfo{}
for _, lang := range languages {
cexts = append(cexts, lang)
loads = append(loads, lang.Loads()...)
for kind, info := range lang.Kinds() {
kinds[kind] = info
}
}
c, err := newUpdateReposConfiguration(args, cexts)
if err != nil {
return err
}
uc := getUpdateReposConfig(c)
workspacePath := filepath.Join(c.RepoRoot, "WORKSPACE")
f, err := rule.LoadFile(workspacePath, "")
if err != nil {
return fmt.Errorf("error loading %q: %v", workspacePath, err)
}
merger.FixWorkspace(f)
if err := uc.fn(uc, f, kinds); err != nil {
return err
}
merger.FixLoads(f, loads)
if err := merger.CheckGazelleLoaded(f); err != nil {
return err
}
if err := f.Save(f.Path); err != nil {
return fmt.Errorf("error writing %q: %v", f.Path, err)
}
return nil
}
func newUpdateReposConfiguration(args []string, cexts []config.Configurer) (*config.Config, error) {
c := config.New()
fs := flag.NewFlagSet("gazelle", flag.ContinueOnError)
// Flag will call this on any parse error. Don't print usage unless
// -h or -help were passed explicitly.
fs.Usage = func() {}
for _, cext := range cexts {
cext.RegisterFlags(fs, "update-repos", c)
}
if err := fs.Parse(args); err != nil {
if err == flag.ErrHelp {
updateReposUsage(fs)
return nil, err
}
// flag already prints the error; don't print it again.
return nil, errors.New("Try -help for more information")
}
for _, cext := range cexts {
if err := cext.CheckFlags(fs, c); err != nil {
return nil, err
}
}
return c, nil
}
func updateReposUsage(fs *flag.FlagSet) {
fmt.Fprint(os.Stderr, `usage:
# Add/update repositories by import path
gazelle update-repos example.com/repo1 example.com/repo2
# Import repositories from lock file
gazelle update-repos -from_file=file
The update-repos command updates repository rules in the WORKSPACE file.
update-repos can add or update repositories explicitly by import path.
update-repos can also import repository rules from a vendoring tool's lock
file (currently only deps' Gopkg.lock is supported).
FLAGS:
`)
}
func updateImportPaths(c *updateReposConfig, f *rule.File, kinds map[string]rule.KindInfo) error {
rs := repos.ListRepositories(f)
rc := repos.NewRemoteCache(rs)
genRules := make([]*rule.Rule, len(c.importPaths))
errs := make([]error, len(c.importPaths))
var wg sync.WaitGroup
wg.Add(len(c.importPaths))
for i, imp := range c.importPaths {
go func(i int, imp string) {
defer wg.Done()
repo, err := repos.UpdateRepo(rc, imp)
if err != nil {
errs[i] = err
return
}
repo.Remote = "" // don't set these explicitly
repo.VCS = ""
rule := repos.GenerateRule(repo)
genRules[i] = rule
}(i, imp)
}
wg.Wait()
for _, err := range errs {
if err != nil {
return err
}
}
merger.MergeFile(f, nil, genRules, merger.PreResolve, kinds)
return nil
}
func importFromLockFile(c *updateReposConfig, f *rule.File, kinds map[string]rule.KindInfo) error {
genRules, err := repos.ImportRepoRules(c.lockFilename)
if err != nil {
return err
}
merger.MergeFile(f, nil, genRules, merger.PreResolve, kinds)
return nil
}

View File

@@ -1,65 +0,0 @@
/* Copyright 2018 The Bazel Authors. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"io/ioutil"
"log"
"path/filepath"
"regexp"
"github.com/bazelbuild/bazel-gazelle/internal/config"
"github.com/bazelbuild/bazel-gazelle/internal/repos"
"github.com/bazelbuild/bazel-gazelle/internal/version"
)
var minimumRulesGoVersion = version.Version{0, 13, 0}
// checkRulesGoVersion checks whether a compatible version of rules_go is
// being used in the workspace. A message will be logged if an incompatible
// version is found.
//
// Note that we can't always determine the version of rules_go in use. Also,
// if we find an incompatible version, we shouldn't bail out since the
// incompatibility may not matter in the current workspace.
func checkRulesGoVersion(repoRoot string) {
const message = `Gazelle may not be compatible with this version of rules_go.
Update io_bazel_rules_go to a newer version in your WORKSPACE file.`
rulesGoPath, err := repos.FindExternalRepo(repoRoot, config.RulesGoRepoName)
if err != nil {
return
}
defBzlPath := filepath.Join(rulesGoPath, "go", "def.bzl")
defBzlContent, err := ioutil.ReadFile(defBzlPath)
if err != nil {
return
}
versionRe := regexp.MustCompile(`(?m)^RULES_GO_VERSION = ['"]([0-9.]*)['"]`)
match := versionRe.FindSubmatch(defBzlContent)
if match == nil {
log.Printf("RULES_GO_VERSION not found in @%s//go:def.bzl.\n%s", config.RulesGoRepoName, message)
return
}
vstr := string(match[1])
v, err := version.ParseVersion(vstr)
if err != nil {
log.Printf("RULES_GO_VERSION %q could not be parsed in @%s//go:def.bzl.\n%s", vstr, config.RulesGoRepoName, message)
}
if v.Compare(minimumRulesGoVersion) < 0 {
log.Printf("Found RULES_GO_VERSION %s. Minimum compatible version is %s.\n%s", v, minimumRulesGoVersion, message)
}
}

View File

@@ -1,30 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"config.go",
"constants.go",
],
importmap = "sigs.k8s.io/kind/vendor/github.com/bazelbuild/bazel-gazelle/internal/config",
importpath = "github.com/bazelbuild/bazel-gazelle/internal/config",
visibility = ["//vendor/github.com/bazelbuild/bazel-gazelle:__subpackages__"],
deps = [
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/rule:go_default_library",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/wspace:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -1,269 +0,0 @@
/* Copyright 2017 The Bazel Authors. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package config
import (
"flag"
"fmt"
"go/build"
"path/filepath"
"strings"
"github.com/bazelbuild/bazel-gazelle/internal/rule"
"github.com/bazelbuild/bazel-gazelle/internal/wspace"
)
// Config holds information about how Gazelle should run. This is based on
// command line arguments, directives, other hints in build files.
//
// A Config applies to a single directory. A Config is created for the
// repository root directory, then copied and modified for each subdirectory.
//
// Config itself contains only general information. Most configuration
// information is language-specific and is stored in Exts. This information
// is modified by extensions that implement Configurer.
type Config struct {
// Dirs is a list of absolute, canonical paths to directories where Gazelle
// should run.
Dirs []string
// RepoRoot is the absolute, canonical path to the root directory of the
// repository with all symlinks resolved.
RepoRoot string
// RepoName is the name of the repository.
RepoName string
// ReadBuildFilesDir is the absolute path to a directory where
// build files should be read from instead of RepoRoot.
ReadBuildFilesDir string
// WriteBuildFilesDir is the absolute path to a directory where
// build files should be written to instead of RepoRoot.
WriteBuildFilesDir string
// ValidBuildFileNames is a list of base names that are considered valid
// build files. Some repositories may have files named "BUILD" that are not
// used by Bazel and should be ignored. Must contain at least one string.
ValidBuildFileNames []string
// ShouldFix determines whether Gazelle attempts to remove and replace
// usage of deprecated rules.
ShouldFix bool
// Exts is a set of configurable extensions. Generally, each language
// has its own set of extensions, but other modules may provide their own
// extensions as well. Values in here may be populated by command line
// arguments, directives in build files, or other mechanisms.
Exts map[string]interface{}
}
func New() *Config {
return &Config{
ValidBuildFileNames: DefaultValidBuildFileNames,
Exts: make(map[string]interface{}),
}
}
// Clone creates a copy of the configuration for use in a subdirectory.
// Note that the Exts map is copied, but its contents are not.
// Configurer.Configure should do this, if needed.
func (c *Config) Clone() *Config {
cc := *c
cc.Exts = make(map[string]interface{})
for k, v := range c.Exts {
cc.Exts[k] = v
}
return &cc
}
var DefaultValidBuildFileNames = []string{"BUILD.bazel", "BUILD"}
func (c *Config) IsValidBuildFileName(name string) bool {
for _, n := range c.ValidBuildFileNames {
if name == n {
return true
}
}
return false
}
func (c *Config) DefaultBuildFileName() string {
return c.ValidBuildFileNames[0]
}
// Configurer is the interface for language or library-specific configuration
// extensions. Most (ideally all) modifications to Config should happen
// via this interface.
type Configurer interface {
// RegisterFlags registers command-line flags used by the extension. This
// method is called once with the root configuration when Gazelle
// starts. RegisterFlags may set an initial values in Config.Exts. When flags
// are set, they should modify these values.
RegisterFlags(fs *flag.FlagSet, cmd string, c *Config)
// CheckFlags validates the configuration after command line flags are parsed.
// This is called once with the root configuration when Gazelle starts.
// CheckFlags may set default values in flags or make implied changes.
CheckFlags(fs *flag.FlagSet, c *Config) error
// KnownDirectives returns a list of directive keys that this Configurer can
// interpret. Gazelle prints errors for directives that are not recoginized by
// any Configurer.
KnownDirectives() []string
// Configure modifies the configuration using directives and other information
// extracted from a build file. Configure is called in each directory.
//
// c is the configuration for the current directory. It starts out as a copy
// of the configuration for the parent directory.
//
// rel is the slash-separated relative path from the repository root to
// the current directory. It is "" for the root directory itself.
//
// f is the build file for the current directory or nil if there is no
// existing build file.
Configure(c *Config, rel string, f *rule.File)
}
// CommonConfigurer handles language-agnostic command-line flags and directives,
// i.e., those that apply to Config itself and not to Config.Exts.
type CommonConfigurer struct {
repoRoot, buildFileNames, readBuildFilesDir, writeBuildFilesDir string
}
func (cc *CommonConfigurer) RegisterFlags(fs *flag.FlagSet, cmd string, c *Config) {
fs.StringVar(&cc.repoRoot, "repo_root", "", "path to a directory which corresponds to go_prefix, otherwise gazelle searches for it.")
fs.StringVar(&cc.buildFileNames, "build_file_name", strings.Join(DefaultValidBuildFileNames, ","), "comma-separated list of valid build file names.\nThe first element of the list is the name of output build files to generate.")
fs.StringVar(&cc.readBuildFilesDir, "experimental_read_build_files_dir", "", "path to a directory where build files should be read from (instead of -repo_root)")
fs.StringVar(&cc.writeBuildFilesDir, "experimental_write_build_files_dir", "", "path to a directory where build files should be written to (instead of -repo_root)")
}
func (cc *CommonConfigurer) CheckFlags(fs *flag.FlagSet, c *Config) error {
var err error
if cc.repoRoot == "" {
cc.repoRoot, err = wspace.Find(".")
if err != nil {
return fmt.Errorf("-repo_root not specified, and WORKSPACE cannot be found: %v", err)
}
}
c.RepoRoot, err = filepath.Abs(cc.repoRoot)
if err != nil {
return fmt.Errorf("%s: failed to find absolute path of repo root: %v", cc.repoRoot, err)
}
c.RepoRoot, err = filepath.EvalSymlinks(c.RepoRoot)
if err != nil {
return fmt.Errorf("%s: failed to resolve symlinks: %v", cc.repoRoot, err)
}
c.ValidBuildFileNames = strings.Split(cc.buildFileNames, ",")
if cc.readBuildFilesDir != "" {
c.ReadBuildFilesDir, err = filepath.Abs(cc.readBuildFilesDir)
if err != nil {
return fmt.Errorf("%s: failed to find absolute path of -read_build_files_dir: %v", cc.readBuildFilesDir, err)
}
}
if cc.writeBuildFilesDir != "" {
c.WriteBuildFilesDir, err = filepath.Abs(cc.writeBuildFilesDir)
if err != nil {
return fmt.Errorf("%s: failed to find absolute path of -write_build_files_dir: %v", cc.writeBuildFilesDir, err)
}
}
return nil
}
func (cc *CommonConfigurer) KnownDirectives() []string {
return []string{"build_file_name"}
}
func (cc *CommonConfigurer) Configure(c *Config, rel string, f *rule.File) {
if f == nil {
return
}
for _, d := range f.Directives {
if d.Key == "build_file_name" {
c.ValidBuildFileNames = strings.Split(d.Value, ",")
}
}
}
// CheckPrefix checks that a string may be used as a prefix. We forbid local
// (relative) imports and those beginning with "/". We allow the empty string,
// but generated rules must not have an empty importpath.
func CheckPrefix(prefix string) error {
if strings.HasPrefix(prefix, "/") || build.IsLocalImport(prefix) {
return fmt.Errorf("invalid prefix: %q", prefix)
}
return nil
}
// DependencyMode determines how imports of packages outside of the prefix
// are resolved.
type DependencyMode int
const (
// ExternalMode indicates imports should be resolved to external dependencies
// (declared in WORKSPACE).
ExternalMode DependencyMode = iota
// VendorMode indicates imports should be resolved to libraries in the
// vendor directory.
VendorMode
)
// DependencyModeFromString converts a string from the command line
// to a DependencyMode. Valid strings are "external", "vendor". An error will
// be returned for an invalid string.
func DependencyModeFromString(s string) (DependencyMode, error) {
switch s {
case "external":
return ExternalMode, nil
case "vendored":
return VendorMode, nil
default:
return 0, fmt.Errorf("unrecognized dependency mode: %q", s)
}
}
// ProtoMode determines how proto rules are generated.
type ProtoMode int
const (
// DefaultProtoMode generates proto_library and new grpc_proto_library rules.
// .pb.go files are excluded when there is a .proto file with a similar name.
DefaultProtoMode ProtoMode = iota
// DisableProtoMode ignores .proto files. .pb.go files are treated
// as normal sources.
DisableProtoMode
// LegacyProtoMode generates filegroups for .proto files if .pb.go files
// are present in the same directory.
LegacyProtoMode
)
func ProtoModeFromString(s string) (ProtoMode, error) {
switch s {
case "default":
return DefaultProtoMode, nil
case "disable":
return DisableProtoMode, nil
case "legacy":
return LegacyProtoMode, nil
default:
return 0, fmt.Errorf("unrecognized proto mode: %q", s)
}
}

View File

@@ -1,68 +0,0 @@
/* Copyright 2017 The Bazel Authors. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package config
const (
// RulesGoRepoName is the canonical name of the rules_go repository. It must
// match the workspace name in WORKSPACE.
RulesGoRepoName = "io_bazel_rules_go"
// DefaultLibName is the name of the default go_library rule in a Go
// package directory. It must be consistent to DEFAULT_LIB in go/private/common.bf.
DefaultLibName = "go_default_library"
// DefaultTestName is a name of an internal test corresponding to
// DefaultLibName. It does not need to be consistent to something but it
// just needs to be unique in the Bazel package
DefaultTestName = "go_default_test"
// DefaultXTestName is a name of an external test corresponding to
// DefaultLibName.
DefaultXTestName = "go_default_xtest"
// DefaultProtosName is the name of a filegroup created
// whenever the library contains .pb.go files
DefaultProtosName = "go_default_library_protos"
// DefaultCgoLibName is the name of the default cgo_library rule in a Go package directory.
DefaultCgoLibName = "cgo_default_library"
// GrpcCompilerLabel is the label for the gRPC compiler plugin, used in the
// "compilers" attribute of go_proto_library rules.
GrpcCompilerLabel = "@io_bazel_rules_go//proto:go_grpc"
// GazelleImportsKey is an internal attribute that lists imported packages
// on generated rules. It is replaced with "deps" during import resolution.
GazelleImportsKey = "_gazelle_imports"
)
// Language is the name of a programming langauge that Gazelle knows about.
// This is used to specify import paths.
type Language int
const (
// GoLang marks Go targets.
GoLang Language = iota
// ProtoLang marks protocol buffer targets.
ProtoLang
)
func (l Language) String() string {
switch l {
case GoLang:
return "go"
case ProtoLang:
return "proto"
default:
return "unknown"
}
}

View File

@@ -1,23 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["flag.go"],
importmap = "sigs.k8s.io/kind/vendor/github.com/bazelbuild/bazel-gazelle/internal/flag",
importpath = "github.com/bazelbuild/bazel-gazelle/internal/flag",
visibility = ["//vendor/github.com/bazelbuild/bazel-gazelle:__subpackages__"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -1,60 +0,0 @@
// Copyright 2017 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package flag
import (
stdflag "flag"
"strings"
)
// MultiFlag allows repeated string flags to be collected into a slice
type MultiFlag struct {
Values *[]string
}
var _ stdflag.Value = (*MultiFlag)(nil)
func (m *MultiFlag) Set(v string) error {
*m.Values = append(*m.Values, v)
return nil
}
func (m *MultiFlag) String() string {
if m == nil || m.Values == nil {
return ""
}
return strings.Join(*m.Values, ",")
}
// ExplicitFlag is a string flag that tracks whether it was set.
type ExplicitFlag struct {
IsSet *bool
Value *string
}
var _ stdflag.Value = (*ExplicitFlag)(nil)
func (f *ExplicitFlag) Set(value string) error {
*f.IsSet = true
*f.Value = value
return nil
}
func (f *ExplicitFlag) String() string {
if f == nil || f.Value == nil {
return ""
}
return *f.Value
}

View File

@@ -1,24 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["label.go"],
importmap = "sigs.k8s.io/kind/vendor/github.com/bazelbuild/bazel-gazelle/internal/label",
importpath = "github.com/bazelbuild/bazel-gazelle/internal/label",
visibility = ["//vendor/github.com/bazelbuild/bazel-gazelle:__subpackages__"],
deps = ["//vendor/github.com/bazelbuild/bazel-gazelle/internal/pathtools:go_default_library"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -1,173 +0,0 @@
/* Copyright 2016 The Bazel Authors. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package label
import (
"fmt"
"log"
"path"
"regexp"
"strings"
"github.com/bazelbuild/bazel-gazelle/internal/pathtools"
)
// A Label represents a label of a build target in Bazel.
type Label struct {
Repo, Pkg, Name string
Relative bool
}
func New(repo, pkg, name string) Label {
return Label{Repo: repo, Pkg: pkg, Name: name}
}
// NoLabel is the nil value of Label. It is not a valid label and may be
// returned when an error occurs.
var NoLabel = Label{}
var (
labelRepoRegexp = regexp.MustCompile(`^[A-Za-z][A-Za-z0-9_]*$`)
labelPkgRegexp = regexp.MustCompile(`^[A-Za-z0-9/._-]*$`)
labelNameRegexp = regexp.MustCompile(`^[A-Za-z0-9_/.+=,@~-]*$`)
)
// Parse reads a label from a string.
// See https://docs.bazel.build/versions/master/build-ref.html#lexi.
func Parse(s string) (Label, error) {
origStr := s
relative := true
var repo string
if strings.HasPrefix(s, "@") {
relative = false
endRepo := strings.Index(s, "//")
if endRepo < 0 {
return NoLabel, fmt.Errorf("label parse error: repository does not end with '//': %q", origStr)
}
repo = s[len("@"):endRepo]
if !labelRepoRegexp.MatchString(repo) {
return NoLabel, fmt.Errorf("label parse error: repository has invalid characters: %q", origStr)
}
s = s[endRepo:]
}
var pkg string
if strings.HasPrefix(s, "//") {
relative = false
endPkg := strings.Index(s, ":")
if endPkg < 0 {
pkg = s[len("//"):]
s = ""
} else {
pkg = s[len("//"):endPkg]
s = s[endPkg:]
}
if !labelPkgRegexp.MatchString(pkg) {
return NoLabel, fmt.Errorf("label parse error: package has invalid characters: %q", origStr)
}
}
if s == ":" {
return NoLabel, fmt.Errorf("label parse error: empty name: %q", origStr)
}
name := strings.TrimPrefix(s, ":")
if !labelNameRegexp.MatchString(name) {
return NoLabel, fmt.Errorf("label parse error: name has invalid characters: %q", origStr)
}
if pkg == "" && name == "" {
return NoLabel, fmt.Errorf("label parse error: empty package and name: %q", origStr)
}
if name == "" {
name = path.Base(pkg)
}
return Label{
Repo: repo,
Pkg: pkg,
Name: name,
Relative: relative,
}, nil
}
func (l Label) String() string {
if l.Relative {
return fmt.Sprintf(":%s", l.Name)
}
var repo string
if l.Repo != "" {
repo = fmt.Sprintf("@%s", l.Repo)
}
if path.Base(l.Pkg) == l.Name {
return fmt.Sprintf("%s//%s", repo, l.Pkg)
}
return fmt.Sprintf("%s//%s:%s", repo, l.Pkg, l.Name)
}
func (l Label) Abs(repo, pkg string) Label {
if !l.Relative {
return l
}
return Label{Repo: repo, Pkg: pkg, Name: l.Name}
}
func (l Label) Rel(repo, pkg string) Label {
if l.Relative || l.Repo != repo {
return l
}
if l.Pkg == pkg {
return Label{Name: l.Name, Relative: true}
}
return Label{Pkg: l.Pkg, Name: l.Name}
}
func (l Label) Equal(other Label) bool {
return l.Repo == other.Repo &&
l.Pkg == other.Pkg &&
l.Name == other.Name &&
l.Relative == other.Relative
}
// Contains returns whether other is contained by the package of l or a
// sub-package. Neither label may be relative.
func (l Label) Contains(other Label) bool {
if l.Relative {
log.Panicf("l must not be relative: %s", l)
}
if other.Relative {
log.Panicf("other must not be relative: %s", other)
}
result := l.Repo == other.Repo && pathtools.HasPrefix(other.Pkg, l.Pkg)
return result
}
// ImportPathToBazelRepoName converts a Go import path into a bazel repo name
// following the guidelines in http://bazel.io/docs/be/functions.html#workspace
func ImportPathToBazelRepoName(importpath string) string {
importpath = strings.ToLower(importpath)
components := strings.Split(importpath, "/")
labels := strings.Split(components[0], ".")
var reversed []string
for i := range labels {
l := labels[len(labels)-i-1]
reversed = append(reversed, l)
}
repo := strings.Join(append(reversed, components[1:]...), "_")
return strings.NewReplacer("-", "_", ".", "_").Replace(repo)
}

View File

@@ -1,32 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["lang.go"],
importmap = "sigs.k8s.io/kind/vendor/github.com/bazelbuild/bazel-gazelle/internal/language",
importpath = "github.com/bazelbuild/bazel-gazelle/internal/language",
visibility = ["//vendor/github.com/bazelbuild/bazel-gazelle:__subpackages__"],
deps = [
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/config:go_default_library",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/resolve:go_default_library",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/rule:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/language/go:all-srcs",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/language/proto:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -1,48 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"config.go",
"constants.go",
"fileinfo.go",
"fix.go",
"generate.go",
"kinds.go",
"known_go_imports.go",
"known_proto_imports.go",
"lang.go",
"package.go",
"resolve.go",
"std_package_list.go",
],
importmap = "sigs.k8s.io/kind/vendor/github.com/bazelbuild/bazel-gazelle/internal/language/go",
importpath = "github.com/bazelbuild/bazel-gazelle/internal/language/go",
visibility = ["//vendor/github.com/bazelbuild/bazel-gazelle:__subpackages__"],
deps = [
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/config:go_default_library",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/flag:go_default_library",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/label:go_default_library",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/language:go_default_library",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/language/proto:go_default_library",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/pathtools:go_default_library",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/repos:go_default_library",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/resolve:go_default_library",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/rule:go_default_library",
"//vendor/github.com/bazelbuild/buildtools/build:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -1,276 +0,0 @@
/* Copyright 2018 The Bazel Authors. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package golang
import (
"flag"
"fmt"
"go/build"
"log"
"path"
"strings"
"github.com/bazelbuild/bazel-gazelle/internal/config"
gzflag "github.com/bazelbuild/bazel-gazelle/internal/flag"
"github.com/bazelbuild/bazel-gazelle/internal/language/proto"
"github.com/bazelbuild/bazel-gazelle/internal/rule"
bzl "github.com/bazelbuild/buildtools/build"
)
// goConfig contains configuration values related to Go rules.
type goConfig struct {
// genericTags is a set of tags that Gazelle considers to be true. Set with
// -build_tags or # gazelle:build_tags. Some tags, like gc, are always on.
genericTags map[string]bool
// prefix is a prefix of an import path, used to generate importpath
// attributes. Set with -go_prefix or # gazelle:prefix.
prefix string
// prefixRel is the package name of the directory where the prefix was set
// ("" for the root directory).
prefixRel string
// prefixSet indicates whether the prefix was set explicitly. It is an error
// to infer an importpath for a rule without setting the prefix.
prefixSet bool
// importMapPrefix is a prefix of a package path, used to generate importmap
// attributes. Set with # gazelle:importmap_prefix.
importMapPrefix string
// importMapPrefixRel is the package name of the directory where importMapPrefix
// was set ("" for the root directory).
importMapPrefixRel string
// depMode determines how imports that are not standard, indexed, or local
// (under the current prefix) should be resolved.
depMode dependencyMode
}
func newGoConfig() *goConfig {
gc := &goConfig{}
gc.preprocessTags()
return gc
}
func getGoConfig(c *config.Config) *goConfig {
return c.Exts[goName].(*goConfig)
}
func (gc *goConfig) clone() *goConfig {
gcCopy := *gc
gcCopy.genericTags = make(map[string]bool)
for k, v := range gc.genericTags {
gcCopy.genericTags[k] = v
}
return &gcCopy
}
// preprocessTags adds some tags which are on by default before they are
// used to match files.
func (gc *goConfig) preprocessTags() {
if gc.genericTags == nil {
gc.genericTags = make(map[string]bool)
}
gc.genericTags["gc"] = true
}
// setBuildTags sets genericTags by parsing as a comma separated list. An
// error will be returned for tags that wouldn't be recognized by "go build".
// preprocessTags should be called before this.
func (gc *goConfig) setBuildTags(tags string) error {
if tags == "" {
return nil
}
for _, t := range strings.Split(tags, ",") {
if strings.HasPrefix(t, "!") {
return fmt.Errorf("build tags can't be negated: %s", t)
}
gc.genericTags[t] = true
}
return nil
}
// dependencyMode determines how imports of packages outside of the prefix
// are resolved.
type dependencyMode int
const (
// externalMode indicates imports should be resolved to external dependencies
// (declared in WORKSPACE).
externalMode dependencyMode = iota
// vendorMode indicates imports should be resolved to libraries in the
// vendor directory.
vendorMode
)
func (m dependencyMode) String() string {
if m == externalMode {
return "external"
} else {
return "vendored"
}
}
type externalFlag struct {
depMode *dependencyMode
}
func (f *externalFlag) Set(value string) error {
switch value {
case "external":
*f.depMode = externalMode
case "vendored":
*f.depMode = vendorMode
default:
return fmt.Errorf("unrecognized dependency mode: %q", value)
}
return nil
}
func (f *externalFlag) String() string {
if f == nil || f.depMode == nil {
return "external"
}
return f.depMode.String()
}
type tagsFlag func(string) error
func (f tagsFlag) Set(value string) error {
return f(value)
}
func (f tagsFlag) String() string {
return ""
}
func (_ *goLang) KnownDirectives() []string {
return []string{
"build_tags",
"importmap_prefix",
"prefix",
}
}
func (_ *goLang) RegisterFlags(fs *flag.FlagSet, cmd string, c *config.Config) {
gc := newGoConfig()
switch cmd {
case "fix", "update":
fs.Var(
tagsFlag(gc.setBuildTags),
"build_tags",
"comma-separated list of build tags. If not specified, Gazelle will not\n\tfilter sources with build constraints.")
fs.Var(
&gzflag.ExplicitFlag{Value: &gc.prefix, IsSet: &gc.prefixSet},
"go_prefix",
"prefix of import paths in the current workspace")
fs.Var(
&externalFlag{&gc.depMode},
"external",
"external: resolve external packages with go_repository\n\tvendored: resolve external packages as packages in vendor/")
}
c.Exts[goName] = gc
}
func (_ *goLang) CheckFlags(fs *flag.FlagSet, c *config.Config) error {
// The base of the -go_prefix flag may be used to generate proto_library
// rule names when there are no .proto sources (empty rules to be deleted)
// or when the package name can't be determined.
// TODO(jayconrod): deprecate and remove this behavior.
gc := getGoConfig(c)
pc := proto.GetProtoConfig(c)
pc.GoPrefix = gc.prefix
return nil
}
func (_ *goLang) Configure(c *config.Config, rel string, f *rule.File) {
var gc *goConfig
if raw, ok := c.Exts[goName]; !ok {
gc = newGoConfig()
} else {
gc = raw.(*goConfig).clone()
}
c.Exts[goName] = gc
if path.Base(rel) == "vendor" {
gc.importMapPrefix = inferImportPath(gc, rel)
gc.importMapPrefixRel = rel
gc.prefix = ""
gc.prefixRel = rel
}
if f != nil {
setPrefix := func(prefix string) {
if err := checkPrefix(prefix); err != nil {
log.Print(err)
return
}
gc.prefix = prefix
gc.prefixSet = true
gc.prefixRel = rel
}
for _, d := range f.Directives {
switch d.Key {
case "build_tags":
if err := gc.setBuildTags(d.Value); err != nil {
log.Print(err)
continue
}
gc.preprocessTags()
gc.setBuildTags(d.Value)
case "importmap_prefix":
gc.importMapPrefix = d.Value
gc.importMapPrefixRel = rel
case "prefix":
setPrefix(d.Value)
}
}
if !gc.prefixSet {
for _, r := range f.Rules {
switch r.Kind() {
case "go_prefix":
args := r.Args()
if len(args) != 1 {
continue
}
s, ok := args[0].(*bzl.StringExpr)
if !ok {
continue
}
setPrefix(s.Value)
case "gazelle":
if prefix := r.AttrString("prefix"); prefix != "" {
setPrefix(prefix)
}
}
}
}
}
}
// checkPrefix checks that a string may be used as a prefix. We forbid local
// (relative) imports and those beginning with "/". We allow the empty string,
// but generated rules must not have an empty importpath.
func checkPrefix(prefix string) error {
if strings.HasPrefix(prefix, "/") || build.IsLocalImport(prefix) {
return fmt.Errorf("invalid prefix: %q", prefix)
}
return nil
}

View File

@@ -1,27 +0,0 @@
/* Copyright 2018 The Bazel Authors. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package golang
const (
// legacyProtoFilegroupName is the anme of a filegroup created in legacy
// mode for libraries that contained .pb.go files and .proto files.
legacyProtoFilegroupName = "go_default_library_protos"
// wellKnownTypesGoPrefix is the import path for the Go repository containing
// pre-generated code for the Well Known Types.
wellKnownTypesGoPrefix = "github.com/golang/protobuf"
// wellKnownTypesPkg is the package name for the predefined WKTs in rules_go.
wellKnownTypesPkg = "proto/wkt"
)

View File

@@ -1,675 +0,0 @@
/* Copyright 2018 The Bazel Authors. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package golang
import (
"bufio"
"bytes"
"errors"
"fmt"
"go/ast"
"go/parser"
"go/token"
"log"
"os"
"path"
"path/filepath"
"strconv"
"strings"
"unicode"
"unicode/utf8"
"github.com/bazelbuild/bazel-gazelle/internal/config"
"github.com/bazelbuild/bazel-gazelle/internal/language/proto"
"github.com/bazelbuild/bazel-gazelle/internal/rule"
)
// fileInfo holds information used to decide how to build a file. This
// information comes from the file's name, from package and import declarations
// (in .go files), and from +build and cgo comments.
type fileInfo struct {
path string
name string
// ext is the type of file, based on extension.
ext ext
// packageName is the Go package name of a .go file, without the
// "_test" suffix if it was present. It is empty for non-Go files.
packageName string
// importPath is the canonical import path for this file's package.
// This may be read from a package comment (in Go) or a go_package
// option (in proto). This field is empty for files that don't specify
// an import path.
importPath string
// isTest is true if the file stem (the part before the extension)
// ends with "_test.go". This is never true for non-Go files.
isTest bool
// imports is a list of packages imported by a file. It does not include
// "C" or anything from the standard library.
imports []string
// isCgo is true for .go files that import "C".
isCgo bool
// goos and goarch contain the OS and architecture suffixes in the filename,
// if they were present.
goos, goarch string
// tags is a list of build tag lines. Each entry is the trimmed text of
// a line after a "+build" prefix.
tags []tagLine
// copts and clinkopts contain flags that are part of CFLAGS, CPPFLAGS,
// CXXFLAGS, and LDFLAGS directives in cgo comments.
copts, clinkopts []taggedOpts
// hasServices indicates whether a .proto file has service definitions.
hasServices bool
}
// tagLine represents the space-separated disjunction of build tag groups
// in a line comment.
type tagLine []tagGroup
// check returns true if at least one of the tag groups is satisfied.
func (l tagLine) check(c *config.Config, os, arch string) bool {
if len(l) == 0 {
return false
}
for _, g := range l {
if g.check(c, os, arch) {
return true
}
}
return false
}
// tagGroup represents a comma-separated conjuction of build tags.
type tagGroup []string
// check returns true if all of the tags are true. Tags that start with
// "!" are negated (but "!!") is not allowed. Go release tags (e.g., "go1.8")
// are ignored. If the group contains an os or arch tag, but the os or arch
// parameters are empty, check returns false even if the tag is negated.
func (g tagGroup) check(c *config.Config, os, arch string) bool {
goConf := getGoConfig(c)
for _, t := range g {
if strings.HasPrefix(t, "!!") { // bad syntax, reject always
return false
}
not := strings.HasPrefix(t, "!")
if not {
t = t[1:]
}
if isIgnoredTag(t) {
// Release tags are treated as "unknown" and are considered true,
// whether or not they are negated.
continue
}
var match bool
if _, ok := rule.KnownOSSet[t]; ok {
if os == "" {
return false
}
match = os == t
} else if _, ok := rule.KnownArchSet[t]; ok {
if arch == "" {
return false
}
match = arch == t
} else {
match = goConf.genericTags[t]
}
if not {
match = !match
}
if !match {
return false
}
}
return true
}
// taggedOpts a list of compile or link options which should only be applied
// if the given set of build tags are satisfied. These options have already
// been tokenized using the same algorithm that "go build" uses, then joined
// with OptSeparator.
type taggedOpts struct {
tags tagLine
opts string
}
// optSeparator is a special character inserted between options that appeared
// together in a #cgo directive. This allows options to be split, modified,
// and escaped by other packages.
//
// It's important to keep options grouped together in the same string. For
// example, if we have "-framework IOKit" together in a #cgo directive,
// "-framework" shouldn't be treated as a separate string for the purposes of
// sorting and de-duplicating.
const optSeparator = "\x1D"
// ext indicates how a file should be treated, based on extension.
type ext int
const (
// unknownExt is applied files that aren't buildable with Go.
unknownExt ext = iota
// goExt is applied to .go files.
goExt
// cExt is applied to C and C++ files.
cExt
// hExt is applied to header files. If cgo code is present, these may be
// C or C++ headers. If not, they are treated as Go assembly headers.
hExt
// sExt is applied to Go assembly files, ending with .s.
sExt
// csExt is applied to other assembly files, ending with .S. These are built
// with the C compiler if cgo code is present.
csExt
// protoExt is applied to .proto files.
protoExt
)
// fileNameInfo returns information that can be inferred from the name of
// a file. It does not read data from the file.
func fileNameInfo(path_ string) fileInfo {
name := filepath.Base(path_)
var ext ext
switch path.Ext(name) {
case ".go":
ext = goExt
case ".c", ".cc", ".cpp", ".cxx", ".m", ".mm":
ext = cExt
case ".h", ".hh", ".hpp", ".hxx":
ext = hExt
case ".s":
ext = sExt
case ".S":
ext = csExt
case ".proto":
ext = protoExt
default:
ext = unknownExt
}
// Determine test, goos, and goarch. This is intended to match the logic
// in goodOSArchFile in go/build.
var isTest bool
var goos, goarch string
l := strings.Split(name[:len(name)-len(path.Ext(name))], "_")
if len(l) >= 2 && l[len(l)-1] == "test" {
isTest = ext == goExt
l = l[:len(l)-1]
}
switch {
case len(l) >= 3 && rule.KnownOSSet[l[len(l)-2]] && rule.KnownArchSet[l[len(l)-1]]:
goos = l[len(l)-2]
goarch = l[len(l)-1]
case len(l) >= 2 && rule.KnownOSSet[l[len(l)-1]]:
goos = l[len(l)-1]
case len(l) >= 2 && rule.KnownArchSet[l[len(l)-1]]:
goarch = l[len(l)-1]
}
return fileInfo{
path: path_,
name: name,
ext: ext,
isTest: isTest,
goos: goos,
goarch: goarch,
}
}
// otherFileInfo returns information about a non-.go file. It will parse
// part of the file to determine build tags. If the file can't be read, an
// error will be logged, and partial information will be returned.
func otherFileInfo(path string) fileInfo {
info := fileNameInfo(path)
if info.ext == unknownExt {
return info
}
tags, err := readTags(info.path)
if err != nil {
log.Printf("%s: error reading file: %v", info.path, err)
return info
}
info.tags = tags
return info
}
// goFileInfo returns information about a .go file. It will parse part of the
// file to determine the package name, imports, and build constraints.
// If the file can't be read, an error will be logged, and partial information
// will be returned.
// This function is intended to match go/build.Context.Import.
// TODD(#53): extract canonical import path
func goFileInfo(path, rel string) fileInfo {
info := fileNameInfo(path)
fset := token.NewFileSet()
pf, err := parser.ParseFile(fset, info.path, nil, parser.ImportsOnly|parser.ParseComments)
if err != nil {
log.Printf("%s: error reading go file: %v", info.path, err)
return info
}
info.packageName = pf.Name.Name
if info.isTest && strings.HasSuffix(info.packageName, "_test") {
info.packageName = info.packageName[:len(info.packageName)-len("_test")]
}
for _, decl := range pf.Decls {
d, ok := decl.(*ast.GenDecl)
if !ok {
continue
}
for _, dspec := range d.Specs {
spec, ok := dspec.(*ast.ImportSpec)
if !ok {
continue
}
quoted := spec.Path.Value
path, err := strconv.Unquote(quoted)
if err != nil {
log.Printf("%s: error reading go file: %v", info.path, err)
continue
}
if path == "C" {
if info.isTest {
log.Printf("%s: warning: use of cgo in test not supported", info.path)
}
info.isCgo = true
cg := spec.Doc
if cg == nil && len(d.Specs) == 1 {
cg = d.Doc
}
if cg != nil {
if err := saveCgo(&info, rel, cg); err != nil {
log.Printf("%s: error reading go file: %v", info.path, err)
}
}
continue
}
info.imports = append(info.imports, path)
}
}
tags, err := readTags(info.path)
if err != nil {
log.Printf("%s: error reading go file: %v", info.path, err)
return info
}
info.tags = tags
return info
}
// saveCgo extracts CFLAGS, CPPFLAGS, CXXFLAGS, and LDFLAGS directives
// from a comment above a "C" import. This is intended to match logic in
// go/build.Context.saveCgo.
func saveCgo(info *fileInfo, rel string, cg *ast.CommentGroup) error {
text := cg.Text()
for _, line := range strings.Split(text, "\n") {
orig := line
// Line is
// #cgo [GOOS/GOARCH...] LDFLAGS: stuff
//
line = strings.TrimSpace(line)
if len(line) < 5 || line[:4] != "#cgo" || (line[4] != ' ' && line[4] != '\t') {
continue
}
// Split at colon.
line = strings.TrimSpace(line[4:])
i := strings.Index(line, ":")
if i < 0 {
return fmt.Errorf("%s: invalid #cgo line: %s", info.path, orig)
}
line, optstr := strings.TrimSpace(line[:i]), strings.TrimSpace(line[i+1:])
// Parse tags and verb.
f := strings.Fields(line)
if len(f) < 1 {
return fmt.Errorf("%s: invalid #cgo line: %s", info.path, orig)
}
verb := f[len(f)-1]
tags := parseTagsInGroups(f[:len(f)-1])
// Parse options.
opts, err := splitQuoted(optstr)
if err != nil {
return fmt.Errorf("%s: invalid #cgo line: %s", info.path, orig)
}
var ok bool
for i, opt := range opts {
if opt, ok = expandSrcDir(opt, rel); !ok {
return fmt.Errorf("%s: malformed #cgo argument: %s", info.path, orig)
}
opts[i] = opt
}
joinedStr := strings.Join(opts, optSeparator)
// Add tags to appropriate list.
switch verb {
case "CFLAGS", "CPPFLAGS", "CXXFLAGS":
info.copts = append(info.copts, taggedOpts{tags, joinedStr})
case "LDFLAGS":
info.clinkopts = append(info.clinkopts, taggedOpts{tags, joinedStr})
case "pkg-config":
return fmt.Errorf("%s: pkg-config not supported: %s", info.path, orig)
default:
return fmt.Errorf("%s: invalid #cgo verb: %s", info.path, orig)
}
}
return nil
}
// splitQuoted splits the string s around each instance of one or more consecutive
// white space characters while taking into account quotes and escaping, and
// returns an array of substrings of s or an empty list if s contains only white space.
// Single quotes and double quotes are recognized to prevent splitting within the
// quoted region, and are removed from the resulting substrings. If a quote in s
// isn't closed err will be set and r will have the unclosed argument as the
// last element. The backslash is used for escaping.
//
// For example, the following string:
//
// a b:"c d" 'e''f' "g\""
//
// Would be parsed as:
//
// []string{"a", "b:c d", "ef", `g"`}
//
// Copied from go/build.splitQuoted
func splitQuoted(s string) (r []string, err error) {
var args []string
arg := make([]rune, len(s))
escaped := false
quoted := false
quote := '\x00'
i := 0
for _, rune := range s {
switch {
case escaped:
escaped = false
case rune == '\\':
escaped = true
continue
case quote != '\x00':
if rune == quote {
quote = '\x00'
continue
}
case rune == '"' || rune == '\'':
quoted = true
quote = rune
continue
case unicode.IsSpace(rune):
if quoted || i > 0 {
quoted = false
args = append(args, string(arg[:i]))
i = 0
}
continue
}
arg[i] = rune
i++
}
if quoted || i > 0 {
args = append(args, string(arg[:i]))
}
if quote != 0 {
err = errors.New("unclosed quote")
} else if escaped {
err = errors.New("unfinished escaping")
}
return args, err
}
// expandSrcDir expands any occurrence of ${SRCDIR}, making sure
// the result is safe for the shell.
//
// Copied from go/build.expandSrcDir
func expandSrcDir(str string, srcdir string) (string, bool) {
// "\" delimited paths cause safeCgoName to fail
// so convert native paths with a different delimiter
// to "/" before starting (eg: on windows).
srcdir = filepath.ToSlash(srcdir)
// Spaces are tolerated in ${SRCDIR}, but not anywhere else.
chunks := strings.Split(str, "${SRCDIR}")
if len(chunks) < 2 {
return str, safeCgoName(str, false)
}
ok := true
for _, chunk := range chunks {
ok = ok && (chunk == "" || safeCgoName(chunk, false))
}
ok = ok && (srcdir == "" || safeCgoName(srcdir, true))
res := strings.Join(chunks, srcdir)
return res, ok && res != ""
}
// NOTE: $ is not safe for the shell, but it is allowed here because of linker options like -Wl,$ORIGIN.
// We never pass these arguments to a shell (just to programs we construct argv for), so this should be okay.
// See golang.org/issue/6038.
// The @ is for OS X. See golang.org/issue/13720.
// The % is for Jenkins. See golang.org/issue/16959.
const safeString = "+-.,/0123456789=ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz:$@%"
const safeSpaces = " "
var safeBytes = []byte(safeSpaces + safeString)
// Copied from go/build.safeCgoName
func safeCgoName(s string, spaces bool) bool {
if s == "" {
return false
}
safe := safeBytes
if !spaces {
safe = safe[len(safeSpaces):]
}
for i := 0; i < len(s); i++ {
if c := s[i]; c < utf8.RuneSelf && bytes.IndexByte(safe, c) < 0 {
return false
}
}
return true
}
// readTags reads and extracts build tags from the block of comments
// and blank lines at the start of a file which is separated from the
// rest of the file by a blank line. Each string in the returned slice
// is the trimmed text of a line after a "+build" prefix.
// Based on go/build.Context.shouldBuild.
func readTags(path string) ([]tagLine, error) {
f, err := os.Open(path)
if err != nil {
return nil, err
}
defer f.Close()
scanner := bufio.NewScanner(f)
// Pass 1: Identify leading run of // comments and blank lines,
// which must be followed by a blank line.
var lines []string
end := 0
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
if line == "" {
end = len(lines)
continue
}
if strings.HasPrefix(line, "//") {
lines = append(lines, line[len("//"):])
continue
}
break
}
if err := scanner.Err(); err != nil {
return nil, err
}
lines = lines[:end]
// Pass 2: Process each line in the run.
var tagLines []tagLine
for _, line := range lines {
fields := strings.Fields(line)
if len(fields) > 0 && fields[0] == "+build" {
tagLines = append(tagLines, parseTagsInGroups(fields[1:]))
}
}
return tagLines, nil
}
func parseTagsInGroups(groups []string) tagLine {
var l tagLine
for _, g := range groups {
l = append(l, tagGroup(strings.Split(g, ",")))
}
return l
}
func isOSArchSpecific(info fileInfo, cgoTags tagLine) (osSpecific, archSpecific bool) {
if info.goos != "" {
osSpecific = true
}
if info.goarch != "" {
archSpecific = true
}
lines := info.tags
if len(cgoTags) > 0 {
lines = append(lines, cgoTags)
}
for _, line := range lines {
for _, group := range line {
for _, tag := range group {
if strings.HasPrefix(tag, "!") {
tag = tag[1:]
}
_, osOk := rule.KnownOSSet[tag]
if osOk {
osSpecific = true
}
_, archOk := rule.KnownArchSet[tag]
if archOk {
archSpecific = true
}
}
}
}
return osSpecific, archSpecific
}
// checkConstraints determines whether build constraints are satisfied on
// a given platform.
//
// The first few arguments describe the platform. genericTags is the set
// of build tags that are true on all platforms. os and arch are the platform
// GOOS and GOARCH strings. If os or arch is empty, checkConstraints will
// return false in the presence of OS and architecture constraints, even
// if they are negated.
//
// The remaining arguments describe the file being tested. All of these may
// be empty or nil. osSuffix and archSuffix are filename suffixes. fileTags
// is a list tags from +build comments found near the top of the file. cgoTags
// is an extra set of tags in a #cgo directive.
func checkConstraints(c *config.Config, os, arch, osSuffix, archSuffix string, fileTags []tagLine, cgoTags tagLine) bool {
if osSuffix != "" && osSuffix != os || archSuffix != "" && archSuffix != arch {
return false
}
for _, l := range fileTags {
if !l.check(c, os, arch) {
return false
}
}
if len(cgoTags) > 0 && !cgoTags.check(c, os, arch) {
return false
}
return true
}
// isIgnoredTag returns whether the tag is "cgo" or is a release tag.
// Release tags match the pattern "go[0-9]\.[0-9]+".
// Gazelle won't consider whether an ignored tag is satisfied when evaluating
// build constraints for a file.
func isIgnoredTag(tag string) bool {
if tag == "cgo" || tag == "race" || tag == "msan" {
return true
}
if len(tag) < 5 || !strings.HasPrefix(tag, "go") {
return false
}
if tag[2] < '0' || tag[2] > '9' || tag[3] != '.' {
return false
}
for _, c := range tag[4:] {
if c < '0' || c > '9' {
return false
}
}
return true
}
// protoFileInfo extracts metadata from a proto file. The proto extension
// already "parses" these and stores metadata in proto.FileInfo, so this is
// just processing relevant options.
func protoFileInfo(path_ string, protoInfo proto.FileInfo) fileInfo {
info := fileNameInfo(path_)
// Look for "option go_package". If there's no / in the package option, then
// it's just a simple package name, not a full import path.
for _, opt := range protoInfo.Options {
if opt.Key != "go_package" {
continue
}
if strings.LastIndexByte(opt.Value, '/') == -1 {
info.packageName = opt.Value
} else {
if i := strings.LastIndexByte(opt.Value, ';'); i != -1 {
info.importPath = opt.Value[:i]
info.packageName = opt.Value[i+1:]
} else {
info.importPath = opt.Value
info.packageName = path.Base(opt.Value)
}
}
}
// Set the Go package name from the proto package name if there was no
// option go_package.
if info.packageName == "" && protoInfo.PackageName != "" {
info.packageName = strings.Replace(protoInfo.PackageName, ".", "_", -1)
}
info.imports = protoInfo.Imports
info.hasServices = protoInfo.HasServices
return info
}

View File

@@ -1,254 +0,0 @@
/* Copyright 2017 The Bazel Authors. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package golang
import (
"log"
"github.com/bazelbuild/bazel-gazelle/internal/config"
"github.com/bazelbuild/bazel-gazelle/internal/language/proto"
"github.com/bazelbuild/bazel-gazelle/internal/rule"
bzl "github.com/bazelbuild/buildtools/build"
)
func (_ *goLang) Fix(c *config.Config, f *rule.File) {
migrateLibraryEmbed(c, f)
migrateGrpcCompilers(c, f)
flattenSrcs(c, f)
squashCgoLibrary(c, f)
squashXtest(c, f)
removeLegacyProto(c, f)
removeLegacyGazelle(c, f)
}
// migrateLibraryEmbed converts "library" attributes to "embed" attributes,
// preserving comments. This only applies to Go rules, and only if there is
// no keep comment on "library" and no existing "embed" attribute.
func migrateLibraryEmbed(c *config.Config, f *rule.File) {
for _, r := range f.Rules {
if !isGoRule(r.Kind()) {
continue
}
libExpr := r.Attr("library")
if libExpr == nil || rule.ShouldKeep(libExpr) || r.Attr("embed") != nil {
continue
}
r.DelAttr("library")
r.SetAttr("embed", &bzl.ListExpr{List: []bzl.Expr{libExpr}})
}
}
// migrateGrpcCompilers converts "go_grpc_library" rules into "go_proto_library"
// rules with a "compilers" attribute.
func migrateGrpcCompilers(c *config.Config, f *rule.File) {
for _, r := range f.Rules {
if r.Kind() != "go_grpc_library" || r.ShouldKeep() || r.Attr("compilers") != nil {
continue
}
r.SetKind("go_proto_library")
r.SetAttr("compilers", []string{config.GrpcCompilerLabel})
}
}
// squashCgoLibrary removes cgo_library rules with the default name and
// merges their attributes with go_library with the default name. If no
// go_library rule exists, a new one will be created.
//
// Note that the library attribute is disregarded, so cgo_library and
// go_library attributes will be squashed even if the cgo_library was unlinked.
// MergeFile will remove unused values and attributes later.
func squashCgoLibrary(c *config.Config, f *rule.File) {
// Find the default cgo_library and go_library rules.
var cgoLibrary, goLibrary *rule.Rule
for _, r := range f.Rules {
if r.Kind() == "cgo_library" && r.Name() == config.DefaultCgoLibName && !r.ShouldKeep() {
if cgoLibrary != nil {
log.Printf("%s: when fixing existing file, multiple cgo_library rules with default name found", f.Path)
continue
}
cgoLibrary = r
continue
}
if r.Kind() == "go_library" && r.Name() == config.DefaultLibName {
if goLibrary != nil {
log.Printf("%s: when fixing existing file, multiple go_library rules with default name referencing cgo_library found", f.Path)
}
goLibrary = r
continue
}
}
if cgoLibrary == nil {
return
}
if !c.ShouldFix {
log.Printf("%s: cgo_library is deprecated. Run 'gazelle fix' to squash with go_library.", f.Path)
return
}
if goLibrary == nil {
cgoLibrary.SetKind("go_library")
cgoLibrary.SetName(config.DefaultLibName)
cgoLibrary.SetAttr("cgo", true)
return
}
if err := rule.SquashRules(cgoLibrary, goLibrary, f.Path); err != nil {
log.Print(err)
return
}
goLibrary.DelAttr("embed")
goLibrary.SetAttr("cgo", true)
cgoLibrary.Delete()
}
// squashXtest removes go_test rules with the default external name and merges
// their attributes with a go_test rule with the default internal name. If
// no internal go_test rule exists, a new one will be created (effectively
// renaming the old rule).
func squashXtest(c *config.Config, f *rule.File) {
// Search for internal and external tests.
var itest, xtest *rule.Rule
for _, r := range f.Rules {
if r.Kind() != "go_test" {
continue
}
if r.Name() == config.DefaultTestName {
itest = r
} else if r.Name() == config.DefaultXTestName {
xtest = r
}
}
if xtest == nil || xtest.ShouldKeep() || (itest != nil && itest.ShouldKeep()) {
return
}
if !c.ShouldFix {
if itest == nil {
log.Printf("%s: go_default_xtest is no longer necessary. Run 'gazelle fix' to rename to go_default_test.", f.Path)
} else {
log.Printf("%s: go_default_xtest is no longer necessary. Run 'gazelle fix' to squash with go_default_test.", f.Path)
}
return
}
// If there was no internal test, we can just rename the external test.
if itest == nil {
xtest.SetName(config.DefaultTestName)
return
}
// Attempt to squash.
if err := rule.SquashRules(xtest, itest, f.Path); err != nil {
log.Print(err)
return
}
xtest.Delete()
}
// flattenSrcs transforms srcs attributes structured as concatenations of
// lists and selects (generated from PlatformStrings; see
// extractPlatformStringsExprs for matching details) into a sorted,
// de-duplicated list. Comments are accumulated and de-duplicated across
// duplicate expressions.
func flattenSrcs(c *config.Config, f *rule.File) {
for _, r := range f.Rules {
if !isGoRule(r.Kind()) {
continue
}
oldSrcs := r.Attr("srcs")
if oldSrcs == nil {
continue
}
flatSrcs := rule.FlattenExpr(oldSrcs)
if flatSrcs != oldSrcs {
r.SetAttr("srcs", flatSrcs)
}
}
}
// removeLegacyProto removes uses of the old proto rules. It deletes loads
// from go_proto_library.bzl. It deletes proto filegroups. It removes
// go_proto_library attributes which are no longer recognized. New rules
// are generated in place of the deleted rules, but attributes and comments
// are not migrated.
func removeLegacyProto(c *config.Config, f *rule.File) {
// Don't fix if the proto mode was set to something other than the default.
pc := proto.GetProtoConfig(c)
if pc.Mode != proto.DefaultMode {
return
}
// Scan for definitions to delete.
var protoLoads []*rule.Load
for _, l := range f.Loads {
if l.Name() == "@io_bazel_rules_go//proto:go_proto_library.bzl" {
protoLoads = append(protoLoads, l)
}
}
var protoFilegroups, protoRules []*rule.Rule
for _, r := range f.Rules {
if r.Kind() == "filegroup" && r.Name() == legacyProtoFilegroupName {
protoFilegroups = append(protoFilegroups, r)
}
if r.Kind() == "go_proto_library" {
protoRules = append(protoRules, r)
}
}
if len(protoLoads)+len(protoFilegroups) == 0 {
return
}
if !c.ShouldFix {
log.Printf("%s: go_proto_library.bzl is deprecated. Run 'gazelle fix' to replace old rules.", f.Path)
return
}
// Delete legacy proto loads and filegroups. Only delete go_proto_library
// rules if we deleted a load.
for _, l := range protoLoads {
l.Delete()
}
for _, r := range protoFilegroups {
r.Delete()
}
if len(protoLoads) > 0 {
for _, r := range protoRules {
r.Delete()
}
}
}
// removeLegacyGazelle removes loads of the "gazelle" macro from
// @io_bazel_rules_go//go:def.bzl. The definition has moved to
// @bazel_gazelle//:def.bzl, and the old one will be deleted soon.
func removeLegacyGazelle(c *config.Config, f *rule.File) {
for _, l := range f.Loads {
if l.Name() == "@io_bazel_rules_go//go:def.bzl" && l.Has("gazelle") {
l.Remove("gazelle")
if l.IsEmpty() {
l.Delete()
}
}
}
}
func isGoRule(kind string) bool {
return kind == "go_library" ||
kind == "go_binary" ||
kind == "go_test" ||
kind == "go_proto_library" ||
kind == "go_grpc_library"
}

View File

@@ -1,570 +0,0 @@
/* Copyright 2018 The Bazel Authors. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package golang
import (
"fmt"
"go/build"
"log"
"path"
"path/filepath"
"sort"
"strings"
"sync"
"github.com/bazelbuild/bazel-gazelle/internal/config"
"github.com/bazelbuild/bazel-gazelle/internal/language/proto"
"github.com/bazelbuild/bazel-gazelle/internal/pathtools"
"github.com/bazelbuild/bazel-gazelle/internal/rule"
)
func (gl *goLang) GenerateRules(c *config.Config, dir, rel string, f *rule.File, subdirs, regularFiles, genFiles []string, otherEmpty, otherGen []*rule.Rule) (empty, gen []*rule.Rule) {
// Extract information about proto files. We need this to exclude .pb.go
// files and generate go_proto_library rules.
gc := getGoConfig(c)
pc := proto.GetProtoConfig(c)
var protoRuleNames []string
protoPackages := make(map[string]proto.Package)
protoFileInfo := make(map[string]proto.FileInfo)
for _, r := range otherGen {
if r.Kind() != "proto_library" {
continue
}
pkg := r.PrivateAttr(proto.PackageKey).(proto.Package)
protoPackages[r.Name()] = pkg
for name, info := range pkg.Files {
protoFileInfo[name] = info
}
protoRuleNames = append(protoRuleNames, r.Name())
}
sort.Strings(protoRuleNames)
var emptyProtoRuleNames []string
for _, r := range otherEmpty {
if r.Kind() == "proto_library" {
emptyProtoRuleNames = append(emptyProtoRuleNames, r.Name())
}
}
// If proto rule generation is enabled, exclude .pb.go files that correspond
// to any .proto files present.
if !pc.Mode.ShouldIncludePregeneratedFiles() {
keep := func(f string) bool {
if strings.HasSuffix(f, ".pb.go") {
_, ok := protoFileInfo[strings.TrimSuffix(f, ".pb.go")+".proto"]
return !ok
}
return true
}
filterFiles(&regularFiles, keep)
filterFiles(&genFiles, keep)
}
// Split regular files into files which can determine the package name and
// import path and other files.
var goFiles, otherFiles []string
for _, f := range regularFiles {
if strings.HasSuffix(f, ".go") {
goFiles = append(goFiles, f)
} else {
otherFiles = append(otherFiles, f)
}
}
// Look for a subdirectory named testdata. Only treat it as data if it does
// not contain a buildable package.
var hasTestdata bool
for _, sub := range subdirs {
if sub == "testdata" {
hasTestdata = !gl.goPkgRels[path.Join(rel, "testdata")]
break
}
}
// Build a set of packages from files in this directory.
goPackageMap, goFilesWithUnknownPackage := buildPackages(c, dir, rel, goFiles, hasTestdata)
// Select a package to generate rules for. If there is no package, create
// an empty package so we can generate empty rules.
var protoName string
pkg, err := selectPackage(c, dir, goPackageMap)
if err != nil {
if _, ok := err.(*build.NoGoError); ok {
if len(protoPackages) == 1 {
for name, ppkg := range protoPackages {
pkg = &goPackage{
name: goProtoPackageName(ppkg),
importPath: goProtoImportPath(gc, ppkg, rel),
proto: protoTargetFromProtoPackage(name, ppkg),
}
protoName = name
break
}
} else {
pkg = emptyPackage(c, dir, rel)
}
} else {
log.Print(err)
}
}
// Try to link the selected package with a proto package.
if pkg != nil {
if pkg.importPath == "" {
if err := pkg.inferImportPath(c); err != nil && pkg.firstGoFile() != "" {
inferImportPathErrorOnce.Do(func() { log.Print(err) })
}
}
for _, name := range protoRuleNames {
ppkg := protoPackages[name]
if pkg.importPath == goProtoImportPath(gc, ppkg, rel) {
protoName = name
pkg.proto = protoTargetFromProtoPackage(name, ppkg)
break
}
}
}
// Generate rules for proto packages. These should come before the other
// Go rules.
g := newGenerator(c, f, rel)
var rules []*rule.Rule
var protoEmbed string
for _, name := range protoRuleNames {
ppkg := protoPackages[name]
var rs []*rule.Rule
if name == protoName {
protoEmbed, rs = g.generateProto(pc.Mode, pkg.proto, pkg.importPath)
} else {
target := protoTargetFromProtoPackage(name, ppkg)
importPath := goProtoImportPath(gc, ppkg, rel)
_, rs = g.generateProto(pc.Mode, target, importPath)
}
rules = append(rules, rs...)
}
for _, name := range emptyProtoRuleNames {
goProtoName := strings.TrimSuffix(name, "_proto") + "_go_proto"
empty = append(empty, rule.NewRule("go_proto_library", goProtoName))
}
if pkg != nil && pc.Mode == proto.PackageMode && pkg.firstGoFile() == "" {
// In proto package mode, don't generate a go_library embedding a
// go_proto_library unless there are actually go files.
protoEmbed = ""
}
// Complete the Go package and generate rules for that.
if pkg != nil {
// Add files with unknown packages. This happens when there are parse
// or I/O errors. We should keep the file in the srcs list and let the
// compiler deal with the error.
cgo := pkg.haveCgo()
for _, info := range goFilesWithUnknownPackage {
if err := pkg.addFile(c, info, cgo); err != nil {
log.Print(err)
}
}
// Process the other static files.
for _, file := range otherFiles {
info := otherFileInfo(filepath.Join(dir, file))
if err := pkg.addFile(c, info, cgo); err != nil {
log.Print(err)
}
}
// Process generated files. Note that generated files may have the same names
// as static files. Bazel will use the generated files, but we will look at
// the content of static files, assuming they will be the same.
regularFileSet := make(map[string]bool)
for _, f := range regularFiles {
regularFileSet[f] = true
}
for _, f := range genFiles {
if regularFileSet[f] {
continue
}
info := fileNameInfo(filepath.Join(dir, f))
if err := pkg.addFile(c, info, cgo); err != nil {
log.Print(err)
}
}
// Generate Go rules.
if protoName == "" {
// Empty proto rules for deletion.
_, rs := g.generateProto(pc.Mode, pkg.proto, pkg.importPath)
rules = append(rules, rs...)
}
lib := g.generateLib(pkg, protoEmbed)
var libName string
if !lib.IsEmpty(goKinds[lib.Kind()]) {
libName = lib.Name()
}
rules = append(rules, lib)
rules = append(rules,
g.generateBin(pkg, libName),
g.generateTest(pkg, libName))
}
for _, r := range rules {
if r.IsEmpty(goKinds[r.Kind()]) {
empty = append(empty, r)
} else {
gen = append(gen, r)
}
}
if f != nil || len(gen) > 0 {
gl.goPkgRels[rel] = true
} else {
for _, sub := range subdirs {
if gl.goPkgRels[path.Join(rel, sub)] {
gl.goPkgRels[rel] = true
break
}
}
}
return empty, gen
}
func filterFiles(files *[]string, pred func(string) bool) {
w := 0
for r := 0; r < len(*files); r++ {
f := (*files)[r]
if pred(f) {
(*files)[w] = f
w++
}
}
*files = (*files)[:w]
}
func buildPackages(c *config.Config, dir, rel string, goFiles []string, hasTestdata bool) (packageMap map[string]*goPackage, goFilesWithUnknownPackage []fileInfo) {
// Process .go and .proto files first, since these determine the package name.
packageMap = make(map[string]*goPackage)
for _, f := range goFiles {
path := filepath.Join(dir, f)
info := goFileInfo(path, rel)
if info.packageName == "" {
goFilesWithUnknownPackage = append(goFilesWithUnknownPackage, info)
continue
}
if info.packageName == "documentation" {
// go/build ignores this package
continue
}
if _, ok := packageMap[info.packageName]; !ok {
packageMap[info.packageName] = &goPackage{
name: info.packageName,
dir: dir,
rel: rel,
hasTestdata: hasTestdata,
}
}
if err := packageMap[info.packageName].addFile(c, info, false); err != nil {
log.Print(err)
}
}
return packageMap, goFilesWithUnknownPackage
}
var inferImportPathErrorOnce sync.Once
// selectPackages selects one Go packages out of the buildable packages found
// in a directory. If multiple packages are found, it returns the package
// whose name matches the directory if such a package exists.
func selectPackage(c *config.Config, dir string, packageMap map[string]*goPackage) (*goPackage, error) {
buildablePackages := make(map[string]*goPackage)
for name, pkg := range packageMap {
if pkg.isBuildable(c) {
buildablePackages[name] = pkg
}
}
if len(buildablePackages) == 0 {
return nil, &build.NoGoError{Dir: dir}
}
if len(buildablePackages) == 1 {
for _, pkg := range buildablePackages {
return pkg, nil
}
}
if pkg, ok := buildablePackages[defaultPackageName(c, dir)]; ok {
return pkg, nil
}
err := &build.MultiplePackageError{Dir: dir}
for name, pkg := range buildablePackages {
// Add the first file for each package for the error message.
// Error() method expects these lists to be the same length. File
// lists must be non-empty. These lists are only created by
// buildPackage for packages with .go files present.
err.Packages = append(err.Packages, name)
err.Files = append(err.Files, pkg.firstGoFile())
}
return nil, err
}
func emptyPackage(c *config.Config, dir, rel string) *goPackage {
pkg := &goPackage{
name: defaultPackageName(c, dir),
dir: dir,
rel: rel,
}
pkg.inferImportPath(c)
return pkg
}
func defaultPackageName(c *config.Config, rel string) string {
gc := getGoConfig(c)
return pathtools.RelBaseName(rel, gc.prefix, "")
}
// hasDefaultVisibility returns whether oldFile contains a "package" rule with
// a "default_visibility" attribute. Rules generated by Gazelle should not
// have their own visibility attributes if this is the case.
func hasDefaultVisibility(oldFile *rule.File) bool {
for _, r := range oldFile.Rules {
if r.Kind() == "package" && r.Attr("default_visibility") != nil {
return true
}
}
return false
}
// checkInternalVisibility overrides the given visibility if the package is
// internal.
func checkInternalVisibility(rel, visibility string) string {
if i := strings.LastIndex(rel, "/internal/"); i >= 0 {
visibility = fmt.Sprintf("//%s:__subpackages__", rel[:i])
} else if strings.HasPrefix(rel, "internal/") {
visibility = "//:__subpackages__"
}
return visibility
}
type generator struct {
c *config.Config
rel string
shouldSetVisibility bool
}
func newGenerator(c *config.Config, f *rule.File, rel string) *generator {
shouldSetVisibility := f == nil || !hasDefaultVisibility(f)
return &generator{c: c, rel: rel, shouldSetVisibility: shouldSetVisibility}
}
func (g *generator) generateProto(mode proto.Mode, target protoTarget, importPath string) (string, []*rule.Rule) {
if !mode.ShouldGenerateRules() && mode != proto.LegacyMode {
// Don't create or delete proto rules in this mode. Any existing rules
// are likely hand-written.
return "", nil
}
filegroupName := config.DefaultProtosName
protoName := target.name
if protoName == "" {
importPath := inferImportPath(getGoConfig(g.c), g.rel)
protoName = proto.RuleName(importPath)
}
goProtoName := strings.TrimSuffix(protoName, "_proto") + "_go_proto"
visibility := []string{checkInternalVisibility(g.rel, "//visibility:public")}
if mode == proto.LegacyMode {
filegroup := rule.NewRule("filegroup", filegroupName)
if target.sources.isEmpty() {
return "", []*rule.Rule{filegroup}
}
filegroup.SetAttr("srcs", target.sources.build())
if g.shouldSetVisibility {
filegroup.SetAttr("visibility", visibility)
}
return "", []*rule.Rule{filegroup}
}
if target.sources.isEmpty() {
return "", []*rule.Rule{
rule.NewRule("filegroup", filegroupName),
rule.NewRule("go_proto_library", goProtoName),
}
}
goProtoLibrary := rule.NewRule("go_proto_library", goProtoName)
goProtoLibrary.SetAttr("proto", ":"+protoName)
g.setImportAttrs(goProtoLibrary, importPath)
if target.hasServices {
goProtoLibrary.SetAttr("compilers", []string{"@io_bazel_rules_go//proto:go_grpc"})
}
if g.shouldSetVisibility {
goProtoLibrary.SetAttr("visibility", visibility)
}
goProtoLibrary.SetPrivateAttr(config.GazelleImportsKey, target.imports.build())
return goProtoName, []*rule.Rule{goProtoLibrary}
}
func (g *generator) generateLib(pkg *goPackage, embed string) *rule.Rule {
goLibrary := rule.NewRule("go_library", config.DefaultLibName)
if !pkg.library.sources.hasGo() && embed == "" {
return goLibrary // empty
}
var visibility string
if pkg.isCommand() {
// Libraries made for a go_binary should not be exposed to the public.
visibility = "//visibility:private"
} else {
visibility = checkInternalVisibility(pkg.rel, "//visibility:public")
}
g.setCommonAttrs(goLibrary, pkg.rel, visibility, pkg.library, embed)
g.setImportAttrs(goLibrary, pkg.importPath)
return goLibrary
}
func (g *generator) generateBin(pkg *goPackage, library string) *rule.Rule {
name := pathtools.RelBaseName(pkg.rel, getGoConfig(g.c).prefix, g.c.RepoRoot)
goBinary := rule.NewRule("go_binary", name)
if !pkg.isCommand() || pkg.binary.sources.isEmpty() && library == "" {
return goBinary // empty
}
visibility := checkInternalVisibility(pkg.rel, "//visibility:public")
g.setCommonAttrs(goBinary, pkg.rel, visibility, pkg.binary, library)
return goBinary
}
func (g *generator) generateTest(pkg *goPackage, library string) *rule.Rule {
goTest := rule.NewRule("go_test", config.DefaultTestName)
if !pkg.test.sources.hasGo() {
return goTest // empty
}
g.setCommonAttrs(goTest, pkg.rel, "", pkg.test, library)
if pkg.hasTestdata {
goTest.SetAttr("data", rule.GlobValue{Patterns: []string{"testdata/**"}})
}
return goTest
}
func (g *generator) setCommonAttrs(r *rule.Rule, pkgRel, visibility string, target goTarget, embed string) {
if !target.sources.isEmpty() {
r.SetAttr("srcs", target.sources.buildFlat())
}
if target.cgo {
r.SetAttr("cgo", true)
}
if !target.clinkopts.isEmpty() {
r.SetAttr("clinkopts", g.options(target.clinkopts.build(), pkgRel))
}
if !target.copts.isEmpty() {
r.SetAttr("copts", g.options(target.copts.build(), pkgRel))
}
if g.shouldSetVisibility && visibility != "" {
r.SetAttr("visibility", []string{visibility})
}
if embed != "" {
r.SetAttr("embed", []string{":" + embed})
}
r.SetPrivateAttr(config.GazelleImportsKey, target.imports.build())
}
func (g *generator) setImportAttrs(r *rule.Rule, importPath string) {
r.SetAttr("importpath", importPath)
goConf := getGoConfig(g.c)
if goConf.importMapPrefix != "" {
fromPrefixRel := pathtools.TrimPrefix(g.rel, goConf.importMapPrefixRel)
importMap := path.Join(goConf.importMapPrefix, fromPrefixRel)
if importMap != importPath {
r.SetAttr("importmap", importMap)
}
}
}
var (
// shortOptPrefixes are strings that come at the beginning of an option
// argument that includes a path, e.g., -Ifoo/bar.
shortOptPrefixes = []string{"-I", "-L", "-F"}
// longOptPrefixes are separate arguments that come before a path argument,
// e.g., -iquote foo/bar.
longOptPrefixes = []string{"-I", "-L", "-F", "-iquote", "-isystem"}
)
// options transforms package-relative paths in cgo options into repository-
// root-relative paths that Bazel can understand. For example, if a cgo file
// in //foo declares an include flag in its copts: "-Ibar", this method
// will transform that flag into "-Ifoo/bar".
func (g *generator) options(opts rule.PlatformStrings, pkgRel string) rule.PlatformStrings {
fixPath := func(opt string) string {
if strings.HasPrefix(opt, "/") {
return opt
}
return path.Clean(path.Join(pkgRel, opt))
}
fixGroups := func(groups []string) ([]string, error) {
fixedGroups := make([]string, len(groups))
for i, group := range groups {
opts := strings.Split(group, optSeparator)
fixedOpts := make([]string, len(opts))
isPath := false
for j, opt := range opts {
if isPath {
opt = fixPath(opt)
isPath = false
goto next
}
for _, short := range shortOptPrefixes {
if strings.HasPrefix(opt, short) && len(opt) > len(short) {
opt = short + fixPath(opt[len(short):])
goto next
}
}
for _, long := range longOptPrefixes {
if opt == long {
isPath = true
goto next
}
}
next:
fixedOpts[j] = escapeOption(opt)
}
fixedGroups[i] = strings.Join(fixedOpts, " ")
}
return fixedGroups, nil
}
opts, errs := opts.MapSlice(fixGroups)
if errs != nil {
log.Panicf("unexpected error when transforming options with pkg %q: %v", pkgRel, errs)
}
return opts
}
func escapeOption(opt string) string {
return strings.NewReplacer(
`\`, `\\`,
`'`, `\'`,
`"`, `\"`,
` `, `\ `,
"\t", "\\\t",
"\n", "\\\n",
"\r", "\\\r",
).Replace(opt)
}

View File

@@ -1,147 +0,0 @@
/* Copyright 2018 The Bazel Authors. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package golang
import "github.com/bazelbuild/bazel-gazelle/internal/rule"
var goKinds = map[string]rule.KindInfo{
"filegroup": {
NonEmptyAttrs: map[string]bool{"srcs": true},
MergeableAttrs: map[string]bool{"srcs": true},
},
"go_binary": {
MatchAny: true,
NonEmptyAttrs: map[string]bool{
"deps": true,
"embed": true,
"srcs": true,
},
SubstituteAttrs: map[string]bool{"embed": true},
MergeableAttrs: map[string]bool{
"cgo": true,
"clinkopts": true,
"copts": true,
"embed": true,
"srcs": true,
},
ResolveAttrs: map[string]bool{"deps": true},
},
"go_library": {
MatchAttrs: []string{"importpath"},
NonEmptyAttrs: map[string]bool{
"deps": true,
"embed": true,
"srcs": true,
},
SubstituteAttrs: map[string]bool{
"embed": true,
},
MergeableAttrs: map[string]bool{
"cgo": true,
"clinkopts": true,
"copts": true,
"embed": true,
"importmap": true,
"importpath": true,
"srcs": true,
},
ResolveAttrs: map[string]bool{"deps": true},
},
"go_proto_library": {
MatchAttrs: []string{"importpath"},
NonEmptyAttrs: map[string]bool{
"deps": true,
"embed": true,
"proto": true,
"srcs": true,
},
SubstituteAttrs: map[string]bool{"proto": true},
MergeableAttrs: map[string]bool{
"srcs": true,
"importpath": true,
"importmap": true,
"cgo": true,
"clinkopts": true,
"copts": true,
"embed": true,
"proto": true,
},
ResolveAttrs: map[string]bool{"deps": true},
},
"go_repository": {
MatchAttrs: []string{"importpath"},
NonEmptyAttrs: nil, // never empty
MergeableAttrs: map[string]bool{
"commit": true,
"importpath": true,
"remote": true,
"sha256": true,
"strip_prefix": true,
"tag": true,
"type": true,
"urls": true,
"vcs": true,
},
},
"go_test": {
NonEmptyAttrs: map[string]bool{
"deps": true,
"embed": true,
"srcs": true,
},
MergeableAttrs: map[string]bool{
"cgo": true,
"clinkopts": true,
"copts": true,
"embed": true,
"srcs": true,
},
ResolveAttrs: map[string]bool{"deps": true},
},
}
var goLoads = []rule.LoadInfo{
{
Name: "@io_bazel_rules_go//go:def.bzl",
Symbols: []string{
"cgo_library",
"go_binary",
"go_library",
"go_prefix",
"go_repository",
"go_test",
},
}, {
Name: "@io_bazel_rules_go//proto:def.bzl",
Symbols: []string{
"go_grpc_library",
"go_proto_library",
},
}, {
Name: "@bazel_gazelle//:deps.bzl",
Symbols: []string{
"go_repository",
},
After: []string{
"go_rules_dependencies",
"go_register_toolchains",
"gazelle_dependencies",
},
},
}
func (_ *goLang) Kinds() map[string]rule.KindInfo { return goKinds }
func (_ *goLang) Loads() []rule.LoadInfo { return goLoads }

View File

@@ -1,136 +0,0 @@
// Generated by internal/language/proto/gen/gen_known_imports.go
// From internal/language/proto/proto.csv
package golang
import "github.com/bazelbuild/bazel-gazelle/internal/label"
var knownGoProtoImports = map[string]label.Label{
"github.com/golang/protobuf/ptypes/any": label.New("io_bazel_rules_go", "proto/wkt", "any_go_proto"),
"google.golang.org/genproto/protobuf/api": label.New("io_bazel_rules_go", "proto/wkt", "api_go_proto"),
"github.com/golang/protobuf/protoc-gen-go/plugin": label.New("io_bazel_rules_go", "proto/wkt", "compiler_plugin_go_proto"),
"github.com/golang/protobuf/protoc-gen-go/descriptor": label.New("io_bazel_rules_go", "proto/wkt", "descriptor_go_proto"),
"github.com/golang/protobuf/ptypes/duration": label.New("io_bazel_rules_go", "proto/wkt", "duration_go_proto"),
"github.com/golang/protobuf/ptypes/empty": label.New("io_bazel_rules_go", "proto/wkt", "empty_go_proto"),
"google.golang.org/genproto/protobuf/field_mask": label.New("io_bazel_rules_go", "proto/wkt", "field_mask_go_proto"),
"google.golang.org/genproto/protobuf/source_context": label.New("io_bazel_rules_go", "proto/wkt", "source_context_go_proto"),
"github.com/golang/protobuf/ptypes/struct": label.New("io_bazel_rules_go", "proto/wkt", "struct_go_proto"),
"github.com/golang/protobuf/ptypes/timestamp": label.New("io_bazel_rules_go", "proto/wkt", "timestamp_go_proto"),
"google.golang.org/genproto/protobuf/ptype": label.New("io_bazel_rules_go", "proto/wkt", "type_go_proto"),
"github.com/golang/protobuf/ptypes/wrappers": label.New("io_bazel_rules_go", "proto/wkt", "wrappers_go_proto"),
"google.golang.org/genproto/googleapis/assistant/embedded/v1alpha2": label.New("go_googleapis", "google/assistant/embedded/v1alpha2", "embedded_go_proto"),
"google.golang.org/genproto/googleapis/assistant/embedded/v1alpha1": label.New("go_googleapis", "google/assistant/embedded/v1alpha1", "embedded_go_proto"),
"google.golang.org/genproto/googleapis/home/graph/v1": label.New("go_googleapis", "google/home/graph/v1", "graph_go_proto"),
"google.golang.org/genproto/googleapis/genomics/v1": label.New("go_googleapis", "google/genomics/v1", "genomics_go_proto"),
"google.golang.org/genproto/googleapis/genomics/v1alpha2": label.New("go_googleapis", "google/genomics/v1alpha2", "genomics_go_proto"),
"google.golang.org/genproto/googleapis/bigtable/v1": label.New("go_googleapis", "google/bigtable/v1", "bigtable_go_proto"),
"google.golang.org/genproto/googleapis/bigtable/admin/cluster/v1": label.New("go_googleapis", "google/bigtable/admin/cluster/v1", "cluster_go_proto"),
"google.golang.org/genproto/googleapis/bigtable/admin/v2": label.New("go_googleapis", "google/bigtable/admin/v2", "admin_go_proto"),
"google.golang.org/genproto/googleapis/bigtable/admin/table/v1": label.New("go_googleapis", "google/bigtable/admin/table/v1", "table_go_proto"),
"google.golang.org/genproto/googleapis/bigtable/v2": label.New("go_googleapis", "google/bigtable/v2", "bigtable_go_proto"),
"google.golang.org/genproto/googleapis/privacy/dlp/v2": label.New("go_googleapis", "google/privacy/dlp/v2", "dlp_go_proto"),
"google.golang.org/genproto/googleapis/watcher/v1": label.New("go_googleapis", "google/watcher/v1", "watcher_go_proto"),
"google.golang.org/genproto/googleapis/firestore/admin/v1beta1": label.New("go_googleapis", "google/firestore/admin/v1beta1", "admin_go_proto"),
"google.golang.org/genproto/googleapis/firestore/v1beta1": label.New("go_googleapis", "google/firestore/v1beta1", "firestore_go_proto"),
"google.golang.org/genproto/googleapis/example/library/v1": label.New("go_googleapis", "google/example/library/v1", "library_go_proto"),
"google.golang.org/genproto/googleapis/appengine/v1": label.New("go_googleapis", "google/appengine/v1", "appengine_go_proto"),
"google.golang.org/genproto/googleapis/appengine/legacy": label.New("go_googleapis", "google/appengine/legacy", "legacy_go_proto"),
"google.golang.org/genproto/googleapis/appengine/logging/v1": label.New("go_googleapis", "google/appengine/logging/v1", "logging_go_proto"),
"google.golang.org/genproto/googleapis/storagetransfer/v1": label.New("go_googleapis", "google/storagetransfer/v1", "storagetransfer_go_proto"),
"google.golang.org/genproto/googleapis/longrunning": label.New("go_googleapis", "google/longrunning", "longrunning_go_proto"),
"google.golang.org/genproto/googleapis/container/v1": label.New("go_googleapis", "google/container/v1", "container_go_proto"),
"google.golang.org/genproto/googleapis/container/v1beta1": label.New("go_googleapis", "google/container/v1beta1", "container_go_proto"),
"google.golang.org/genproto/googleapis/container/v1alpha1": label.New("go_googleapis", "google/container/v1alpha1", "container_go_proto"),
"google.golang.org/genproto/googleapis/datastore/v1beta3": label.New("go_googleapis", "google/datastore/v1beta3", "datastore_go_proto"),
"google.golang.org/genproto/googleapis/datastore/v1": label.New("go_googleapis", "google/datastore/v1", "datastore_go_proto"),
"google.golang.org/genproto/googleapis/datastore/admin/v1": label.New("go_googleapis", "google/datastore/admin/v1", "admin_go_proto"),
"google.golang.org/genproto/googleapis/datastore/admin/v1beta1": label.New("go_googleapis", "google/datastore/admin/v1beta1", "admin_go_proto"),
"google.golang.org/genproto/googleapis/bytestream": label.New("go_googleapis", "google/bytestream", "bytestream_go_proto"),
"google.golang.org/genproto/googleapis/iam/v1": label.New("go_googleapis", "google/iam/v1", "iam_go_proto"),
"google.golang.org/genproto/googleapis/iam/v1/logging": label.New("go_googleapis", "google/iam/v1/logging", "logging_go_proto"),
"google.golang.org/genproto/googleapis/iam/admin/v1": label.New("go_googleapis", "google/iam/admin/v1", "admin_go_proto"),
"google.golang.org/genproto/googleapis/type/money": label.New("go_googleapis", "google/type", "money_go_proto"),
"google.golang.org/genproto/googleapis/type/latlng": label.New("go_googleapis", "google/type", "latlng_go_proto"),
"google.golang.org/genproto/googleapis/type/color": label.New("go_googleapis", "google/type", "color_go_proto"),
"google.golang.org/genproto/googleapis/type/timeofday": label.New("go_googleapis", "google/type", "timeofday_go_proto"),
"google.golang.org/genproto/googleapis/type/date": label.New("go_googleapis", "google/type", "date_go_proto"),
"google.golang.org/genproto/googleapis/type/dayofweek": label.New("go_googleapis", "google/type", "dayofweek_go_proto"),
"google.golang.org/genproto/googleapis/type/postaladdress": label.New("go_googleapis", "google/type", "postaladdress_go_proto"),
"google.golang.org/genproto/googleapis/devtools/clouderrorreporting/v1beta1": label.New("go_googleapis", "google/devtools/clouderrorreporting/v1beta1", "clouderrorreporting_go_proto"),
"google.golang.org/genproto/googleapis/devtools/resultstore/v2": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"),
"google.golang.org/genproto/googleapis/devtools/source/v1": label.New("go_googleapis", "google/devtools/source/v1", "source_go_proto"),
"google.golang.org/genproto/googleapis/devtools/remoteexecution/v1test": label.New("go_googleapis", "google/devtools/remoteexecution/v1test", "remoteexecution_go_proto"),
"google.golang.org/genproto/googleapis/devtools/cloudbuild/v1": label.New("go_googleapis", "google/devtools/cloudbuild/v1", "cloudbuild_go_proto"),
"google.golang.org/genproto/googleapis/devtools/sourcerepo/v1": label.New("go_googleapis", "google/devtools/sourcerepo/v1", "sourcerepo_go_proto"),
"google.golang.org/genproto/googleapis/devtools/remoteworkers/v1test2": label.New("go_googleapis", "google/devtools/remoteworkers/v1test2", "remoteworkers_go_proto"),
"google.golang.org/genproto/googleapis/devtools/cloudtrace/v1": label.New("go_googleapis", "google/devtools/cloudtrace/v1", "cloudtrace_go_proto"),
"google.golang.org/genproto/googleapis/devtools/cloudtrace/v2": label.New("go_googleapis", "google/devtools/cloudtrace/v2", "cloudtrace_go_proto"),
"google.golang.org/genproto/googleapis/devtools/cloudprofiler/v2": label.New("go_googleapis", "google/devtools/cloudprofiler/v2", "cloudprofiler_go_proto"),
"google.golang.org/genproto/googleapis/devtools/containeranalysis/v1alpha1": label.New("go_googleapis", "google/devtools/containeranalysis/v1alpha1", "containeranalysis_go_proto"),
"google.golang.org/genproto/googleapis/devtools/build/v1": label.New("go_googleapis", "google/devtools/build/v1", "build_go_proto"),
"google.golang.org/genproto/googleapis/devtools/clouddebugger/v2": label.New("go_googleapis", "google/devtools/clouddebugger/v2", "clouddebugger_go_proto"),
"google.golang.org/genproto/googleapis/cloud/resourcemanager/v2": label.New("go_googleapis", "google/cloud/resourcemanager/v2", "resourcemanager_go_proto"),
"google.golang.org/genproto/googleapis/cloud/kms/v1": label.New("go_googleapis", "google/cloud/kms/v1", "kms_go_proto"),
"google.golang.org/genproto/googleapis/cloud/runtimeconfig/v1beta1": label.New("go_googleapis", "google/cloud/runtimeconfig/v1beta1", "runtimeconfig_go_proto"),
"google.golang.org/genproto/googleapis/cloud/tasks/v2beta2": label.New("go_googleapis", "google/cloud/tasks/v2beta2", "tasks_go_proto"),
"google.golang.org/genproto/googleapis/cloud/oslogin/v1": label.New("go_googleapis", "google/cloud/oslogin/v1", "oslogin_go_proto"),
"google.golang.org/genproto/googleapis/cloud/oslogin/v1alpha": label.New("go_googleapis", "google/cloud/oslogin/v1alpha", "oslogin_go_proto"),
"google.golang.org/genproto/googleapis/cloud/oslogin/common": label.New("go_googleapis", "google/cloud/oslogin/common", "common_go_proto"),
"google.golang.org/genproto/googleapis/cloud/oslogin/v1beta": label.New("go_googleapis", "google/cloud/oslogin/v1beta", "oslogin_go_proto"),
"google.golang.org/genproto/googleapis/cloud/dialogflow/v2beta1": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_go_proto"),
"google.golang.org/genproto/googleapis/cloud/dialogflow/v2": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_go_proto"),
"google.golang.org/genproto/googleapis/cloud/redis/v1beta1": label.New("go_googleapis", "google/cloud/redis/v1beta1", "redis_go_proto"),
"google.golang.org/genproto/googleapis/cloud/location": label.New("go_googleapis", "google/cloud/location", "location_go_proto"),
"google.golang.org/genproto/googleapis/cloud/websecurityscanner/v1alpha": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_go_proto"),
"google.golang.org/genproto/googleapis/cloud/language/v1": label.New("go_googleapis", "google/cloud/language/v1", "language_go_proto"),
"google.golang.org/genproto/googleapis/cloud/language/v1beta2": label.New("go_googleapis", "google/cloud/language/v1beta2", "language_go_proto"),
"google.golang.org/genproto/googleapis/cloud/language/v1beta1": label.New("go_googleapis", "google/cloud/language/v1beta1", "language_go_proto"),
"google.golang.org/genproto/googleapis/cloud/bigquery/datatransfer/v1": label.New("go_googleapis", "google/cloud/bigquery/datatransfer/v1", "datatransfer_go_proto"),
"google.golang.org/genproto/googleapis/cloud/bigquery/logging/v1": label.New("go_googleapis", "google/cloud/bigquery/logging/v1", "logging_go_proto"),
"google.golang.org/genproto/googleapis/cloud/vision/v1": label.New("go_googleapis", "google/cloud/vision/v1", "vision_go_proto"),
"google.golang.org/genproto/googleapis/cloud/vision/v1p2beta1": label.New("go_googleapis", "google/cloud/vision/v1p2beta1", "vision_go_proto"),
"google.golang.org/genproto/googleapis/cloud/vision/v1p1beta1": label.New("go_googleapis", "google/cloud/vision/v1p1beta1", "vision_go_proto"),
"google.golang.org/genproto/googleapis/cloud/speech/v1": label.New("go_googleapis", "google/cloud/speech/v1", "speech_go_proto"),
"google.golang.org/genproto/googleapis/cloud/speech/v1beta1": label.New("go_googleapis", "google/cloud/speech/v1beta1", "speech_go_proto"),
"google.golang.org/genproto/googleapis/cloud/speech/v1p1beta1": label.New("go_googleapis", "google/cloud/speech/v1p1beta1", "speech_go_proto"),
"google.golang.org/genproto/googleapis/cloud/iot/v1": label.New("go_googleapis", "google/cloud/iot/v1", "iot_go_proto"),
"google.golang.org/genproto/googleapis/cloud/videointelligence/v1": label.New("go_googleapis", "google/cloud/videointelligence/v1", "videointelligence_go_proto"),
"google.golang.org/genproto/googleapis/cloud/videointelligence/v1beta2": label.New("go_googleapis", "google/cloud/videointelligence/v1beta2", "videointelligence_go_proto"),
"google.golang.org/genproto/googleapis/cloud/videointelligence/v1beta1": label.New("go_googleapis", "google/cloud/videointelligence/v1beta1", "videointelligence_go_proto"),
"google.golang.org/genproto/googleapis/cloud/videointelligence/v1p1beta1": label.New("go_googleapis", "google/cloud/videointelligence/v1p1beta1", "videointelligence_go_proto"),
"google.golang.org/genproto/googleapis/cloud/audit": label.New("go_googleapis", "google/cloud/audit", "audit_go_proto"),
"google.golang.org/genproto/googleapis/cloud/support/common": label.New("go_googleapis", "google/cloud/support", "common_go_proto"),
"google.golang.org/genproto/googleapis/cloud/support/v1alpha1": label.New("go_googleapis", "google/cloud/support/v1alpha1", "support_go_proto"),
"google.golang.org/genproto/googleapis/cloud/ml/v1": label.New("go_googleapis", "google/cloud/ml/v1", "ml_go_proto"),
"google.golang.org/genproto/googleapis/cloud/texttospeech/v1": label.New("go_googleapis", "google/cloud/texttospeech/v1", "texttospeech_go_proto"),
"google.golang.org/genproto/googleapis/cloud/texttospeech/v1beta1": label.New("go_googleapis", "google/cloud/texttospeech/v1beta1", "texttospeech_go_proto"),
"google.golang.org/genproto/googleapis/cloud/functions/v1beta2": label.New("go_googleapis", "google/cloud/functions/v1beta2", "functions_go_proto"),
"google.golang.org/genproto/googleapis/cloud/billing/v1": label.New("go_googleapis", "google/cloud/billing/v1", "billing_go_proto"),
"google.golang.org/genproto/googleapis/cloud/dataproc/v1": label.New("go_googleapis", "google/cloud/dataproc/v1", "dataproc_go_proto"),
"google.golang.org/genproto/googleapis/cloud/dataproc/v1beta2": label.New("go_googleapis", "google/cloud/dataproc/v1beta2", "dataproc_go_proto"),
"google.golang.org/genproto/googleapis/api/serviceconfig": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"),
"google.golang.org/genproto/googleapis/api/annotations": label.New("go_googleapis", "google/api", "annotations_go_proto"),
"google.golang.org/genproto/googleapis/api/configchange": label.New("go_googleapis", "google/api", "configchange_go_proto"),
"google.golang.org/genproto/googleapis/api/distribution": label.New("go_googleapis", "google/api", "distribution_go_proto"),
"google.golang.org/genproto/googleapis/api/monitoredres": label.New("go_googleapis", "google/api", "monitoredres_go_proto"),
"google.golang.org/genproto/googleapis/api/metric": label.New("go_googleapis", "google/api", "metric_go_proto"),
"google.golang.org/genproto/googleapis/api/label": label.New("go_googleapis", "google/api", "label_go_proto"),
"google.golang.org/genproto/googleapis/api/httpbody": label.New("go_googleapis", "google/api", "httpbody_go_proto"),
"google.golang.org/genproto/googleapis/api": label.New("go_googleapis", "google/api/experimental", "api_go_proto"),
"google.golang.org/genproto/googleapis/api/servicemanagement/v1": label.New("go_googleapis", "google/api/servicemanagement/v1", "servicemanagement_go_proto"),
"google.golang.org/genproto/googleapis/api/servicecontrol/v1": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_go_proto"),
"google.golang.org/genproto/googleapis/pubsub/v1": label.New("go_googleapis", "google/pubsub/v1", "pubsub_go_proto"),
"google.golang.org/genproto/googleapis/pubsub/v1beta2": label.New("go_googleapis", "google/pubsub/v1beta2", "pubsub_go_proto"),
"google.golang.org/genproto/googleapis/spanner/v1": label.New("go_googleapis", "google/spanner/v1", "spanner_go_proto"),
"google.golang.org/genproto/googleapis/spanner/admin/database/v1": label.New("go_googleapis", "google/spanner/admin/database/v1", "database_go_proto"),
"google.golang.org/genproto/googleapis/spanner/admin/instance/v1": label.New("go_googleapis", "google/spanner/admin/instance/v1", "instance_go_proto"),
"google.golang.org/genproto/googleapis/monitoring/v3": label.New("go_googleapis", "google/monitoring/v3", "monitoring_go_proto"),
"google.golang.org/genproto/googleapis/rpc/code": label.New("go_googleapis", "google/rpc", "code_go_proto"),
"google.golang.org/genproto/googleapis/rpc/status": label.New("go_googleapis", "google/rpc", "status_go_proto"),
"google.golang.org/genproto/googleapis/rpc/errdetails": label.New("go_googleapis", "google/rpc", "errdetails_go_proto"),
"google.golang.org/genproto/googleapis/streetview/publish/v1": label.New("go_googleapis", "google/streetview/publish/v1", "publish_go_proto"),
"google.golang.org/genproto/googleapis/logging/v2": label.New("go_googleapis", "google/logging/v2", "logging_go_proto"),
"google.golang.org/genproto/googleapis/logging/type": label.New("go_googleapis", "google/logging/type", "ltype_go_proto"),
}

View File

@@ -1,300 +0,0 @@
// Generated by internal/language/proto/gen/gen_known_imports.go
// From internal/language/proto/proto.csv
package golang
import "github.com/bazelbuild/bazel-gazelle/internal/label"
var knownProtoImports = map[string]label.Label{
"google/protobuf/any.proto": label.New("io_bazel_rules_go", "proto/wkt", "any_go_proto"),
"google/protobuf/api.proto": label.New("io_bazel_rules_go", "proto/wkt", "api_go_proto"),
"google/protobuf/compiler/plugin.proto": label.New("io_bazel_rules_go", "proto/wkt", "compiler_plugin_go_proto"),
"google/protobuf/descriptor.proto": label.New("io_bazel_rules_go", "proto/wkt", "descriptor_go_proto"),
"google/protobuf/duration.proto": label.New("io_bazel_rules_go", "proto/wkt", "duration_go_proto"),
"google/protobuf/empty.proto": label.New("io_bazel_rules_go", "proto/wkt", "empty_go_proto"),
"google/protobuf/field_mask.proto": label.New("io_bazel_rules_go", "proto/wkt", "field_mask_go_proto"),
"google/protobuf/source_context.proto": label.New("io_bazel_rules_go", "proto/wkt", "source_context_go_proto"),
"google/protobuf/struct.proto": label.New("io_bazel_rules_go", "proto/wkt", "struct_go_proto"),
"google/protobuf/timestamp.proto": label.New("io_bazel_rules_go", "proto/wkt", "timestamp_go_proto"),
"google/protobuf/type.proto": label.New("io_bazel_rules_go", "proto/wkt", "type_go_proto"),
"google/protobuf/wrappers.proto": label.New("io_bazel_rules_go", "proto/wkt", "wrappers_go_proto"),
"google/assistant/embedded/v1alpha2/embedded_assistant.proto": label.New("go_googleapis", "google/assistant/embedded/v1alpha2", "embedded_go_proto"),
"google/assistant/embedded/v1alpha1/embedded_assistant.proto": label.New("go_googleapis", "google/assistant/embedded/v1alpha1", "embedded_go_proto"),
"google/home/graph/v1/device.proto": label.New("go_googleapis", "google/home/graph/v1", "graph_go_proto"),
"google/home/graph/v1/homegraph.proto": label.New("go_googleapis", "google/home/graph/v1", "graph_go_proto"),
"google/genomics/v1/operations.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_go_proto"),
"google/genomics/v1/variants.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_go_proto"),
"google/genomics/v1/position.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_go_proto"),
"google/genomics/v1/references.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_go_proto"),
"google/genomics/v1/cigar.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_go_proto"),
"google/genomics/v1/datasets.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_go_proto"),
"google/genomics/v1/readalignment.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_go_proto"),
"google/genomics/v1/annotations.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_go_proto"),
"google/genomics/v1/reads.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_go_proto"),
"google/genomics/v1/readgroup.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_go_proto"),
"google/genomics/v1/readgroupset.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_go_proto"),
"google/genomics/v1/range.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_go_proto"),
"google/genomics/v1alpha2/pipelines.proto": label.New("go_googleapis", "google/genomics/v1alpha2", "genomics_go_proto"),
"google/bigtable/v1/bigtable_service_messages.proto": label.New("go_googleapis", "google/bigtable/v1", "bigtable_go_proto"),
"google/bigtable/v1/bigtable_service.proto": label.New("go_googleapis", "google/bigtable/v1", "bigtable_go_proto"),
"google/bigtable/v1/bigtable_data.proto": label.New("go_googleapis", "google/bigtable/v1", "bigtable_go_proto"),
"google/bigtable/admin/cluster/v1/bigtable_cluster_data.proto": label.New("go_googleapis", "google/bigtable/admin/cluster/v1", "cluster_go_proto"),
"google/bigtable/admin/cluster/v1/bigtable_cluster_service_messages.proto": label.New("go_googleapis", "google/bigtable/admin/cluster/v1", "cluster_go_proto"),
"google/bigtable/admin/cluster/v1/bigtable_cluster_service.proto": label.New("go_googleapis", "google/bigtable/admin/cluster/v1", "cluster_go_proto"),
"google/bigtable/admin/v2/bigtable_instance_admin.proto": label.New("go_googleapis", "google/bigtable/admin/v2", "admin_go_proto"),
"google/bigtable/admin/v2/instance.proto": label.New("go_googleapis", "google/bigtable/admin/v2", "admin_go_proto"),
"google/bigtable/admin/v2/table.proto": label.New("go_googleapis", "google/bigtable/admin/v2", "admin_go_proto"),
"google/bigtable/admin/v2/bigtable_table_admin.proto": label.New("go_googleapis", "google/bigtable/admin/v2", "admin_go_proto"),
"google/bigtable/admin/v2/common.proto": label.New("go_googleapis", "google/bigtable/admin/v2", "admin_go_proto"),
"google/bigtable/admin/table/v1/bigtable_table_service_messages.proto": label.New("go_googleapis", "google/bigtable/admin/table/v1", "table_go_proto"),
"google/bigtable/admin/table/v1/bigtable_table_service.proto": label.New("go_googleapis", "google/bigtable/admin/table/v1", "table_go_proto"),
"google/bigtable/admin/table/v1/bigtable_table_data.proto": label.New("go_googleapis", "google/bigtable/admin/table/v1", "table_go_proto"),
"google/bigtable/v2/bigtable.proto": label.New("go_googleapis", "google/bigtable/v2", "bigtable_go_proto"),
"google/bigtable/v2/data.proto": label.New("go_googleapis", "google/bigtable/v2", "bigtable_go_proto"),
"google/privacy/dlp/v2/storage.proto": label.New("go_googleapis", "google/privacy/dlp/v2", "dlp_go_proto"),
"google/privacy/dlp/v2/dlp.proto": label.New("go_googleapis", "google/privacy/dlp/v2", "dlp_go_proto"),
"google/watcher/v1/watch.proto": label.New("go_googleapis", "google/watcher/v1", "watcher_go_proto"),
"google/firestore/admin/v1beta1/firestore_admin.proto": label.New("go_googleapis", "google/firestore/admin/v1beta1", "admin_go_proto"),
"google/firestore/admin/v1beta1/index.proto": label.New("go_googleapis", "google/firestore/admin/v1beta1", "admin_go_proto"),
"google/firestore/v1beta1/write.proto": label.New("go_googleapis", "google/firestore/v1beta1", "firestore_go_proto"),
"google/firestore/v1beta1/document.proto": label.New("go_googleapis", "google/firestore/v1beta1", "firestore_go_proto"),
"google/firestore/v1beta1/firestore.proto": label.New("go_googleapis", "google/firestore/v1beta1", "firestore_go_proto"),
"google/firestore/v1beta1/query.proto": label.New("go_googleapis", "google/firestore/v1beta1", "firestore_go_proto"),
"google/firestore/v1beta1/common.proto": label.New("go_googleapis", "google/firestore/v1beta1", "firestore_go_proto"),
"google/example/library/v1/library.proto": label.New("go_googleapis", "google/example/library/v1", "library_go_proto"),
"google/appengine/v1/instance.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_go_proto"),
"google/appengine/v1/audit_data.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_go_proto"),
"google/appengine/v1/appengine.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_go_proto"),
"google/appengine/v1/application.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_go_proto"),
"google/appengine/v1/operation.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_go_proto"),
"google/appengine/v1/app_yaml.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_go_proto"),
"google/appengine/v1/location.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_go_proto"),
"google/appengine/v1/service.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_go_proto"),
"google/appengine/v1/deploy.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_go_proto"),
"google/appengine/v1/version.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_go_proto"),
"google/appengine/legacy/audit_data.proto": label.New("go_googleapis", "google/appengine/legacy", "legacy_go_proto"),
"google/appengine/logging/v1/request_log.proto": label.New("go_googleapis", "google/appengine/logging/v1", "logging_go_proto"),
"google/storagetransfer/v1/transfer.proto": label.New("go_googleapis", "google/storagetransfer/v1", "storagetransfer_go_proto"),
"google/storagetransfer/v1/transfer_types.proto": label.New("go_googleapis", "google/storagetransfer/v1", "storagetransfer_go_proto"),
"google/longrunning/operations.proto": label.New("go_googleapis", "google/longrunning", "longrunning_go_proto"),
"google/container/v1/cluster_service.proto": label.New("go_googleapis", "google/container/v1", "container_go_proto"),
"google/container/v1beta1/cluster_service.proto": label.New("go_googleapis", "google/container/v1beta1", "container_go_proto"),
"google/container/v1alpha1/cluster_service.proto": label.New("go_googleapis", "google/container/v1alpha1", "container_go_proto"),
"google/datastore/v1beta3/datastore.proto": label.New("go_googleapis", "google/datastore/v1beta3", "datastore_go_proto"),
"google/datastore/v1beta3/query.proto": label.New("go_googleapis", "google/datastore/v1beta3", "datastore_go_proto"),
"google/datastore/v1beta3/entity.proto": label.New("go_googleapis", "google/datastore/v1beta3", "datastore_go_proto"),
"google/datastore/v1/datastore.proto": label.New("go_googleapis", "google/datastore/v1", "datastore_go_proto"),
"google/datastore/v1/query.proto": label.New("go_googleapis", "google/datastore/v1", "datastore_go_proto"),
"google/datastore/v1/entity.proto": label.New("go_googleapis", "google/datastore/v1", "datastore_go_proto"),
"google/datastore/admin/v1/datastore_admin.proto": label.New("go_googleapis", "google/datastore/admin/v1", "admin_go_proto"),
"google/datastore/admin/v1beta1/datastore_admin.proto": label.New("go_googleapis", "google/datastore/admin/v1beta1", "admin_go_proto"),
"google/bytestream/bytestream.proto": label.New("go_googleapis", "google/bytestream", "bytestream_go_proto"),
"google/iam/v1/iam_policy.proto": label.New("go_googleapis", "google/iam/v1", "iam_go_proto"),
"google/iam/v1/policy.proto": label.New("go_googleapis", "google/iam/v1", "iam_go_proto"),
"google/iam/v1/logging/audit_data.proto": label.New("go_googleapis", "google/iam/v1/logging", "logging_go_proto"),
"google/iam/admin/v1/iam.proto": label.New("go_googleapis", "google/iam/admin/v1", "admin_go_proto"),
"google/type/money.proto": label.New("go_googleapis", "google/type", "money_go_proto"),
"google/type/latlng.proto": label.New("go_googleapis", "google/type", "latlng_go_proto"),
"google/type/color.proto": label.New("go_googleapis", "google/type", "color_go_proto"),
"google/type/timeofday.proto": label.New("go_googleapis", "google/type", "timeofday_go_proto"),
"google/type/date.proto": label.New("go_googleapis", "google/type", "date_go_proto"),
"google/type/dayofweek.proto": label.New("go_googleapis", "google/type", "dayofweek_go_proto"),
"google/type/postal_address.proto": label.New("go_googleapis", "google/type", "postaladdress_go_proto"),
"google/devtools/clouderrorreporting/v1beta1/report_errors_service.proto": label.New("go_googleapis", "google/devtools/clouderrorreporting/v1beta1", "clouderrorreporting_go_proto"),
"google/devtools/clouderrorreporting/v1beta1/error_group_service.proto": label.New("go_googleapis", "google/devtools/clouderrorreporting/v1beta1", "clouderrorreporting_go_proto"),
"google/devtools/clouderrorreporting/v1beta1/error_stats_service.proto": label.New("go_googleapis", "google/devtools/clouderrorreporting/v1beta1", "clouderrorreporting_go_proto"),
"google/devtools/clouderrorreporting/v1beta1/common.proto": label.New("go_googleapis", "google/devtools/clouderrorreporting/v1beta1", "clouderrorreporting_go_proto"),
"google/devtools/resultstore/v2/file.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"),
"google/devtools/resultstore/v2/resultstore_download.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"),
"google/devtools/resultstore/v2/configuration.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"),
"google/devtools/resultstore/v2/action.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"),
"google/devtools/resultstore/v2/resultstore_file_download.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"),
"google/devtools/resultstore/v2/test_suite.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"),
"google/devtools/resultstore/v2/file_set.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"),
"google/devtools/resultstore/v2/coverage.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"),
"google/devtools/resultstore/v2/coverage_summary.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"),
"google/devtools/resultstore/v2/configured_target.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"),
"google/devtools/resultstore/v2/target.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"),
"google/devtools/resultstore/v2/invocation.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"),
"google/devtools/resultstore/v2/common.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_go_proto"),
"google/devtools/source/v1/source_context.proto": label.New("go_googleapis", "google/devtools/source/v1", "source_go_proto"),
"google/devtools/remoteexecution/v1test/remote_execution.proto": label.New("go_googleapis", "google/devtools/remoteexecution/v1test", "remoteexecution_go_proto"),
"google/devtools/cloudbuild/v1/cloudbuild.proto": label.New("go_googleapis", "google/devtools/cloudbuild/v1", "cloudbuild_go_proto"),
"google/devtools/sourcerepo/v1/sourcerepo.proto": label.New("go_googleapis", "google/devtools/sourcerepo/v1", "sourcerepo_go_proto"),
"google/devtools/remoteworkers/v1test2/worker.proto": label.New("go_googleapis", "google/devtools/remoteworkers/v1test2", "remoteworkers_go_proto"),
"google/devtools/remoteworkers/v1test2/tasks.proto": label.New("go_googleapis", "google/devtools/remoteworkers/v1test2", "remoteworkers_go_proto"),
"google/devtools/remoteworkers/v1test2/bots.proto": label.New("go_googleapis", "google/devtools/remoteworkers/v1test2", "remoteworkers_go_proto"),
"google/devtools/remoteworkers/v1test2/command.proto": label.New("go_googleapis", "google/devtools/remoteworkers/v1test2", "remoteworkers_go_proto"),
"google/devtools/cloudtrace/v1/trace.proto": label.New("go_googleapis", "google/devtools/cloudtrace/v1", "cloudtrace_go_proto"),
"google/devtools/cloudtrace/v2/trace.proto": label.New("go_googleapis", "google/devtools/cloudtrace/v2", "cloudtrace_go_proto"),
"google/devtools/cloudtrace/v2/tracing.proto": label.New("go_googleapis", "google/devtools/cloudtrace/v2", "cloudtrace_go_proto"),
"google/devtools/cloudprofiler/v2/profiler.proto": label.New("go_googleapis", "google/devtools/cloudprofiler/v2", "cloudprofiler_go_proto"),
"google/devtools/containeranalysis/v1alpha1/containeranalysis.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1alpha1", "containeranalysis_go_proto"),
"google/devtools/containeranalysis/v1alpha1/bill_of_materials.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1alpha1", "containeranalysis_go_proto"),
"google/devtools/containeranalysis/v1alpha1/provenance.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1alpha1", "containeranalysis_go_proto"),
"google/devtools/containeranalysis/v1alpha1/package_vulnerability.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1alpha1", "containeranalysis_go_proto"),
"google/devtools/containeranalysis/v1alpha1/source_context.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1alpha1", "containeranalysis_go_proto"),
"google/devtools/containeranalysis/v1alpha1/image_basis.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1alpha1", "containeranalysis_go_proto"),
"google/devtools/build/v1/build_events.proto": label.New("go_googleapis", "google/devtools/build/v1", "build_go_proto"),
"google/devtools/build/v1/build_status.proto": label.New("go_googleapis", "google/devtools/build/v1", "build_go_proto"),
"google/devtools/build/v1/publish_build_event.proto": label.New("go_googleapis", "google/devtools/build/v1", "build_go_proto"),
"google/devtools/clouddebugger/v2/debugger.proto": label.New("go_googleapis", "google/devtools/clouddebugger/v2", "clouddebugger_go_proto"),
"google/devtools/clouddebugger/v2/data.proto": label.New("go_googleapis", "google/devtools/clouddebugger/v2", "clouddebugger_go_proto"),
"google/devtools/clouddebugger/v2/controller.proto": label.New("go_googleapis", "google/devtools/clouddebugger/v2", "clouddebugger_go_proto"),
"google/cloud/resourcemanager/v2/folders.proto": label.New("go_googleapis", "google/cloud/resourcemanager/v2", "resourcemanager_go_proto"),
"google/cloud/kms/v1/resources.proto": label.New("go_googleapis", "google/cloud/kms/v1", "kms_go_proto"),
"google/cloud/kms/v1/service.proto": label.New("go_googleapis", "google/cloud/kms/v1", "kms_go_proto"),
"google/cloud/runtimeconfig/v1beta1/resources.proto": label.New("go_googleapis", "google/cloud/runtimeconfig/v1beta1", "runtimeconfig_go_proto"),
"google/cloud/runtimeconfig/v1beta1/runtimeconfig.proto": label.New("go_googleapis", "google/cloud/runtimeconfig/v1beta1", "runtimeconfig_go_proto"),
"google/cloud/tasks/v2beta2/queue.proto": label.New("go_googleapis", "google/cloud/tasks/v2beta2", "tasks_go_proto"),
"google/cloud/tasks/v2beta2/task.proto": label.New("go_googleapis", "google/cloud/tasks/v2beta2", "tasks_go_proto"),
"google/cloud/tasks/v2beta2/target.proto": label.New("go_googleapis", "google/cloud/tasks/v2beta2", "tasks_go_proto"),
"google/cloud/tasks/v2beta2/cloudtasks.proto": label.New("go_googleapis", "google/cloud/tasks/v2beta2", "tasks_go_proto"),
"google/cloud/oslogin/v1/oslogin.proto": label.New("go_googleapis", "google/cloud/oslogin/v1", "oslogin_go_proto"),
"google/cloud/oslogin/v1alpha/oslogin.proto": label.New("go_googleapis", "google/cloud/oslogin/v1alpha", "oslogin_go_proto"),
"google/cloud/oslogin/common/common.proto": label.New("go_googleapis", "google/cloud/oslogin/common", "common_go_proto"),
"google/cloud/oslogin/v1beta/oslogin.proto": label.New("go_googleapis", "google/cloud/oslogin/v1beta", "oslogin_go_proto"),
"google/cloud/dialogflow/v2beta1/context.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_go_proto"),
"google/cloud/dialogflow/v2beta1/session_entity_type.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_go_proto"),
"google/cloud/dialogflow/v2beta1/intent.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_go_proto"),
"google/cloud/dialogflow/v2beta1/entity_type.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_go_proto"),
"google/cloud/dialogflow/v2beta1/webhook.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_go_proto"),
"google/cloud/dialogflow/v2beta1/session.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_go_proto"),
"google/cloud/dialogflow/v2beta1/agent.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_go_proto"),
"google/cloud/dialogflow/v2/context.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_go_proto"),
"google/cloud/dialogflow/v2/session_entity_type.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_go_proto"),
"google/cloud/dialogflow/v2/intent.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_go_proto"),
"google/cloud/dialogflow/v2/entity_type.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_go_proto"),
"google/cloud/dialogflow/v2/webhook.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_go_proto"),
"google/cloud/dialogflow/v2/session.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_go_proto"),
"google/cloud/dialogflow/v2/agent.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_go_proto"),
"google/cloud/redis/v1beta1/cloud_redis.proto": label.New("go_googleapis", "google/cloud/redis/v1beta1", "redis_go_proto"),
"google/cloud/location/locations.proto": label.New("go_googleapis", "google/cloud/location", "location_go_proto"),
"google/cloud/websecurityscanner/v1alpha/finding.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_go_proto"),
"google/cloud/websecurityscanner/v1alpha/finding_type_stats.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_go_proto"),
"google/cloud/websecurityscanner/v1alpha/scan_config.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_go_proto"),
"google/cloud/websecurityscanner/v1alpha/crawled_url.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_go_proto"),
"google/cloud/websecurityscanner/v1alpha/scan_run.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_go_proto"),
"google/cloud/websecurityscanner/v1alpha/web_security_scanner.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_go_proto"),
"google/cloud/websecurityscanner/v1alpha/finding_addon.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_go_proto"),
"google/cloud/language/v1/language_service.proto": label.New("go_googleapis", "google/cloud/language/v1", "language_go_proto"),
"google/cloud/language/v1beta2/language_service.proto": label.New("go_googleapis", "google/cloud/language/v1beta2", "language_go_proto"),
"google/cloud/language/v1beta1/language_service.proto": label.New("go_googleapis", "google/cloud/language/v1beta1", "language_go_proto"),
"google/cloud/bigquery/datatransfer/v1/transfer.proto": label.New("go_googleapis", "google/cloud/bigquery/datatransfer/v1", "datatransfer_go_proto"),
"google/cloud/bigquery/datatransfer/v1/datatransfer.proto": label.New("go_googleapis", "google/cloud/bigquery/datatransfer/v1", "datatransfer_go_proto"),
"google/cloud/bigquery/logging/v1/audit_data.proto": label.New("go_googleapis", "google/cloud/bigquery/logging/v1", "logging_go_proto"),
"google/cloud/vision/v1/image_annotator.proto": label.New("go_googleapis", "google/cloud/vision/v1", "vision_go_proto"),
"google/cloud/vision/v1/geometry.proto": label.New("go_googleapis", "google/cloud/vision/v1", "vision_go_proto"),
"google/cloud/vision/v1/web_detection.proto": label.New("go_googleapis", "google/cloud/vision/v1", "vision_go_proto"),
"google/cloud/vision/v1/text_annotation.proto": label.New("go_googleapis", "google/cloud/vision/v1", "vision_go_proto"),
"google/cloud/vision/v1p2beta1/image_annotator.proto": label.New("go_googleapis", "google/cloud/vision/v1p2beta1", "vision_go_proto"),
"google/cloud/vision/v1p2beta1/geometry.proto": label.New("go_googleapis", "google/cloud/vision/v1p2beta1", "vision_go_proto"),
"google/cloud/vision/v1p2beta1/web_detection.proto": label.New("go_googleapis", "google/cloud/vision/v1p2beta1", "vision_go_proto"),
"google/cloud/vision/v1p2beta1/text_annotation.proto": label.New("go_googleapis", "google/cloud/vision/v1p2beta1", "vision_go_proto"),
"google/cloud/vision/v1p1beta1/image_annotator.proto": label.New("go_googleapis", "google/cloud/vision/v1p1beta1", "vision_go_proto"),
"google/cloud/vision/v1p1beta1/geometry.proto": label.New("go_googleapis", "google/cloud/vision/v1p1beta1", "vision_go_proto"),
"google/cloud/vision/v1p1beta1/web_detection.proto": label.New("go_googleapis", "google/cloud/vision/v1p1beta1", "vision_go_proto"),
"google/cloud/vision/v1p1beta1/text_annotation.proto": label.New("go_googleapis", "google/cloud/vision/v1p1beta1", "vision_go_proto"),
"google/cloud/speech/v1/cloud_speech.proto": label.New("go_googleapis", "google/cloud/speech/v1", "speech_go_proto"),
"google/cloud/speech/v1beta1/cloud_speech.proto": label.New("go_googleapis", "google/cloud/speech/v1beta1", "speech_go_proto"),
"google/cloud/speech/v1p1beta1/cloud_speech.proto": label.New("go_googleapis", "google/cloud/speech/v1p1beta1", "speech_go_proto"),
"google/cloud/iot/v1/device_manager.proto": label.New("go_googleapis", "google/cloud/iot/v1", "iot_go_proto"),
"google/cloud/iot/v1/resources.proto": label.New("go_googleapis", "google/cloud/iot/v1", "iot_go_proto"),
"google/cloud/videointelligence/v1/video_intelligence.proto": label.New("go_googleapis", "google/cloud/videointelligence/v1", "videointelligence_go_proto"),
"google/cloud/videointelligence/v1beta2/video_intelligence.proto": label.New("go_googleapis", "google/cloud/videointelligence/v1beta2", "videointelligence_go_proto"),
"google/cloud/videointelligence/v1beta1/video_intelligence.proto": label.New("go_googleapis", "google/cloud/videointelligence/v1beta1", "videointelligence_go_proto"),
"google/cloud/videointelligence/v1p1beta1/video_intelligence.proto": label.New("go_googleapis", "google/cloud/videointelligence/v1p1beta1", "videointelligence_go_proto"),
"google/cloud/audit/audit_log.proto": label.New("go_googleapis", "google/cloud/audit", "audit_go_proto"),
"google/cloud/support/common.proto": label.New("go_googleapis", "google/cloud/support", "common_go_proto"),
"google/cloud/support/v1alpha1/cloud_support.proto": label.New("go_googleapis", "google/cloud/support/v1alpha1", "support_go_proto"),
"google/cloud/ml/v1/operation_metadata.proto": label.New("go_googleapis", "google/cloud/ml/v1", "ml_go_proto"),
"google/cloud/ml/v1/job_service.proto": label.New("go_googleapis", "google/cloud/ml/v1", "ml_go_proto"),
"google/cloud/ml/v1/prediction_service.proto": label.New("go_googleapis", "google/cloud/ml/v1", "ml_go_proto"),
"google/cloud/ml/v1/model_service.proto": label.New("go_googleapis", "google/cloud/ml/v1", "ml_go_proto"),
"google/cloud/ml/v1/project_service.proto": label.New("go_googleapis", "google/cloud/ml/v1", "ml_go_proto"),
"google/cloud/texttospeech/v1/cloud_tts.proto": label.New("go_googleapis", "google/cloud/texttospeech/v1", "texttospeech_go_proto"),
"google/cloud/texttospeech/v1beta1/cloud_tts.proto": label.New("go_googleapis", "google/cloud/texttospeech/v1beta1", "texttospeech_go_proto"),
"google/cloud/functions/v1beta2/operations.proto": label.New("go_googleapis", "google/cloud/functions/v1beta2", "functions_go_proto"),
"google/cloud/functions/v1beta2/functions.proto": label.New("go_googleapis", "google/cloud/functions/v1beta2", "functions_go_proto"),
"google/cloud/billing/v1/cloud_billing.proto": label.New("go_googleapis", "google/cloud/billing/v1", "billing_go_proto"),
"google/cloud/dataproc/v1/operations.proto": label.New("go_googleapis", "google/cloud/dataproc/v1", "dataproc_go_proto"),
"google/cloud/dataproc/v1/clusters.proto": label.New("go_googleapis", "google/cloud/dataproc/v1", "dataproc_go_proto"),
"google/cloud/dataproc/v1/jobs.proto": label.New("go_googleapis", "google/cloud/dataproc/v1", "dataproc_go_proto"),
"google/cloud/dataproc/v1beta2/operations.proto": label.New("go_googleapis", "google/cloud/dataproc/v1beta2", "dataproc_go_proto"),
"google/cloud/dataproc/v1beta2/clusters.proto": label.New("go_googleapis", "google/cloud/dataproc/v1beta2", "dataproc_go_proto"),
"google/cloud/dataproc/v1beta2/jobs.proto": label.New("go_googleapis", "google/cloud/dataproc/v1beta2", "dataproc_go_proto"),
"google/cloud/dataproc/v1beta2/workflow_templates.proto": label.New("go_googleapis", "google/cloud/dataproc/v1beta2", "dataproc_go_proto"),
"google/cloud/dataproc/v1beta2/shared.proto": label.New("go_googleapis", "google/cloud/dataproc/v1beta2", "dataproc_go_proto"),
"google/api/context.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"),
"google/api/http.proto": label.New("go_googleapis", "google/api", "annotations_go_proto"),
"google/api/config_change.proto": label.New("go_googleapis", "google/api", "configchange_go_proto"),
"google/api/system_parameter.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"),
"google/api/monitoring.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"),
"google/api/distribution.proto": label.New("go_googleapis", "google/api", "distribution_go_proto"),
"google/api/endpoint.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"),
"google/api/usage.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"),
"google/api/monitored_resource.proto": label.New("go_googleapis", "google/api", "monitoredres_go_proto"),
"google/api/annotations.proto": label.New("go_googleapis", "google/api", "annotations_go_proto"),
"google/api/control.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"),
"google/api/metric.proto": label.New("go_googleapis", "google/api", "metric_go_proto"),
"google/api/label.proto": label.New("go_googleapis", "google/api", "label_go_proto"),
"google/api/consumer.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"),
"google/api/log.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"),
"google/api/billing.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"),
"google/api/service.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"),
"google/api/logging.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"),
"google/api/documentation.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"),
"google/api/quota.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"),
"google/api/auth.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"),
"google/api/backend.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"),
"google/api/source_info.proto": label.New("go_googleapis", "google/api", "serviceconfig_go_proto"),
"google/api/httpbody.proto": label.New("go_googleapis", "google/api", "httpbody_go_proto"),
"google/api/experimental/authorization_config.proto": label.New("go_googleapis", "google/api/experimental", "api_go_proto"),
"google/api/experimental/experimental.proto": label.New("go_googleapis", "google/api/experimental", "api_go_proto"),
"google/api/servicemanagement/v1/servicemanager.proto": label.New("go_googleapis", "google/api/servicemanagement/v1", "servicemanagement_go_proto"),
"google/api/servicemanagement/v1/resources.proto": label.New("go_googleapis", "google/api/servicemanagement/v1", "servicemanagement_go_proto"),
"google/api/servicecontrol/v1/quota_controller.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_go_proto"),
"google/api/servicecontrol/v1/distribution.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_go_proto"),
"google/api/servicecontrol/v1/check_error.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_go_proto"),
"google/api/servicecontrol/v1/operation.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_go_proto"),
"google/api/servicecontrol/v1/metric_value.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_go_proto"),
"google/api/servicecontrol/v1/log_entry.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_go_proto"),
"google/api/servicecontrol/v1/service_controller.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_go_proto"),
"google/pubsub/v1/pubsub.proto": label.New("go_googleapis", "google/pubsub/v1", "pubsub_go_proto"),
"google/pubsub/v1beta2/pubsub.proto": label.New("go_googleapis", "google/pubsub/v1beta2", "pubsub_go_proto"),
"google/spanner/v1/mutation.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_go_proto"),
"google/spanner/v1/spanner.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_go_proto"),
"google/spanner/v1/transaction.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_go_proto"),
"google/spanner/v1/keys.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_go_proto"),
"google/spanner/v1/type.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_go_proto"),
"google/spanner/v1/query_plan.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_go_proto"),
"google/spanner/v1/result_set.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_go_proto"),
"google/spanner/admin/database/v1/spanner_database_admin.proto": label.New("go_googleapis", "google/spanner/admin/database/v1", "database_go_proto"),
"google/spanner/admin/instance/v1/spanner_instance_admin.proto": label.New("go_googleapis", "google/spanner/admin/instance/v1", "instance_go_proto"),
"google/monitoring/v3/group.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_go_proto"),
"google/monitoring/v3/mutation_record.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_go_proto"),
"google/monitoring/v3/notification.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_go_proto"),
"google/monitoring/v3/alert_service.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_go_proto"),
"google/monitoring/v3/uptime_service.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_go_proto"),
"google/monitoring/v3/group_service.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_go_proto"),
"google/monitoring/v3/alert.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_go_proto"),
"google/monitoring/v3/uptime.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_go_proto"),
"google/monitoring/v3/metric.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_go_proto"),
"google/monitoring/v3/notification_service.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_go_proto"),
"google/monitoring/v3/metric_service.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_go_proto"),
"google/monitoring/v3/common.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_go_proto"),
"google/rpc/code.proto": label.New("go_googleapis", "google/rpc", "code_go_proto"),
"google/rpc/status.proto": label.New("go_googleapis", "google/rpc", "status_go_proto"),
"google/rpc/error_details.proto": label.New("go_googleapis", "google/rpc", "errdetails_go_proto"),
"google/streetview/publish/v1/resources.proto": label.New("go_googleapis", "google/streetview/publish/v1", "publish_go_proto"),
"google/streetview/publish/v1/rpcmessages.proto": label.New("go_googleapis", "google/streetview/publish/v1", "publish_go_proto"),
"google/streetview/publish/v1/streetview_publish.proto": label.New("go_googleapis", "google/streetview/publish/v1", "publish_go_proto"),
"google/logging/v2/logging_metrics.proto": label.New("go_googleapis", "google/logging/v2", "logging_go_proto"),
"google/logging/v2/logging_config.proto": label.New("go_googleapis", "google/logging/v2", "logging_go_proto"),
"google/logging/v2/log_entry.proto": label.New("go_googleapis", "google/logging/v2", "logging_go_proto"),
"google/logging/v2/logging.proto": label.New("go_googleapis", "google/logging/v2", "logging_go_proto"),
"google/logging/type/log_severity.proto": label.New("go_googleapis", "google/logging/type", "ltype_go_proto"),
"google/logging/type/http_request.proto": label.New("go_googleapis", "google/logging/type", "ltype_go_proto"),
}

View File

@@ -1,71 +0,0 @@
/* Copyright 2018 The Bazel Authors. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package golang provides support for Go and Go proto rules. It generates
// go_library, go_binary, go_test, and go_proto_library rules.
//
// Configuration
//
// Go rules support the flags -build_tags, -go_prefix, and -external.
// They also support the directives # gazelle:build_tags, # gazelle:prefix,
// and # gazelle:importmap_prefix. See
// https://github.com/bazelbuild/bazel-gazelle/blob/master/README.rst#directives
// for information on these.
//
// Rule generation
//
// Currently, Gazelle generates rules for one Go package per directory. In
// general, we aim to support Go code which is compatible with "go build". If
// there are no buildable packages, Gazelle will delete existing rules with
// default names. If there are multiple packages, Gazelle will pick one that
// matches the directory name or will print an error if no such package is
// found.
//
// Gazelle names library and test rules somewhat oddly: go_default_library, and
// go_default_test. This is for historic reasons: before the importpath
// attribute was mandatory, import paths were inferred from label names. Even if
// we never support multiple packages in the future (we should), we should
// migrate away from this because it's surprising. Libraries should generally
// be named after their directories.
//
// Dependency resolution
//
// Go libraries are indexed by their importpath attribute. Gazelle attempts to
// resolve libraries by import path using the index, filtered using the
// vendoring algorithm. If an import doesn't match any known library, Gazelle
// guesses a name for it, locally (if the import path is under the current
// prefix), or in an external repository or vendor directory (depending
// on external mode).
//
// Gazelle has special cases for import paths associated with proto Well
// Known Types and Google APIs. rules_go declares canonical rules for these.
package golang
import "github.com/bazelbuild/bazel-gazelle/internal/language"
const goName = "go"
type goLang struct {
// goPkgDirs is a set of relative paths to directories containing buildable
// Go code, including in subdirectories.
goPkgRels map[string]bool
}
func (_ *goLang) Name() string { return goName }
func New() language.Language {
return &goLang{goPkgRels: make(map[string]bool)}
}

View File

@@ -1,488 +0,0 @@
/* Copyright 2017 The Bazel Authors. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package golang
import (
"fmt"
"log"
"path"
"sort"
"strings"
"github.com/bazelbuild/bazel-gazelle/internal/config"
"github.com/bazelbuild/bazel-gazelle/internal/language/proto"
"github.com/bazelbuild/bazel-gazelle/internal/rule"
)
// goPackage contains metadata for a set of .go and .proto files that can be
// used to generate Go rules.
type goPackage struct {
name, dir, rel string
library, binary, test goTarget
proto protoTarget
hasTestdata bool
importPath string
}
// goTarget contains information used to generate an individual Go rule
// (library, binary, or test).
type goTarget struct {
sources, imports, copts, clinkopts platformStringsBuilder
cgo bool
}
// protoTarget contains information used to generate a go_proto_library rule.
type protoTarget struct {
name string
sources platformStringsBuilder
imports platformStringsBuilder
hasServices bool
}
// platformStringsBuilder is used to construct rule.PlatformStrings. Bazel
// has some requirements for deps list (a dependency cannot appear in more
// than one select expression; dependencies cannot be duplicated), so we need
// to build these carefully.
type platformStringsBuilder struct {
strs map[string]platformStringInfo
}
// platformStringInfo contains information about a single string (source,
// import, or option).
type platformStringInfo struct {
set platformStringSet
oss map[string]bool
archs map[string]bool
platforms map[rule.Platform]bool
}
type platformStringSet int
const (
genericSet platformStringSet = iota
osSet
archSet
platformSet
)
// addFile adds the file described by "info" to a target in the package "p" if
// the file is buildable.
//
// "cgo" tells whether any ".go" file in the package contains cgo code. This
// affects whether C files are added to targets.
//
// An error is returned if a file is buildable but invalid (for example, a
// test .go file containing cgo code). Files that are not buildable will not
// be added to any target (for example, .txt files).
func (pkg *goPackage) addFile(c *config.Config, info fileInfo, cgo bool) error {
switch {
case info.ext == unknownExt || !cgo && (info.ext == cExt || info.ext == csExt):
return nil
case info.ext == protoExt:
if proto.GetProtoConfig(c).Mode == proto.LegacyMode {
// Only add files in legacy mode. This is used to generate a filegroup
// that contains all protos. In order modes, we get the .proto files
// from information emitted by the proto language extension.
pkg.proto.addFile(c, info)
}
case info.isTest:
if info.isCgo {
return fmt.Errorf("%s: use of cgo in test not supported", info.path)
}
pkg.test.addFile(c, info)
default:
pkg.library.addFile(c, info)
}
return nil
}
// isCommand returns true if the package name is "main".
func (pkg *goPackage) isCommand() bool {
return pkg.name == "main"
}
// isBuildable returns true if anything in the package is buildable.
// This is true if the package has Go code that satisfies build constraints
// on any platform or has proto files not in legacy mode.
func (pkg *goPackage) isBuildable(c *config.Config) bool {
return pkg.firstGoFile() != "" || !pkg.proto.sources.isEmpty()
}
// firstGoFile returns the name of a .go file if the package contains at least
// one .go file, or "" otherwise.
func (pkg *goPackage) firstGoFile() string {
goSrcs := []platformStringsBuilder{
pkg.library.sources,
pkg.binary.sources,
pkg.test.sources,
}
for _, sb := range goSrcs {
if sb.strs != nil {
for s := range sb.strs {
if strings.HasSuffix(s, ".go") {
return s
}
}
}
}
return ""
}
func (pkg *goPackage) haveCgo() bool {
return pkg.library.cgo || pkg.binary.cgo || pkg.test.cgo
}
func (pkg *goPackage) inferImportPath(c *config.Config) error {
if pkg.importPath != "" {
log.Panic("importPath already set")
}
gc := getGoConfig(c)
if !gc.prefixSet {
return fmt.Errorf("%s: go prefix is not set, so importpath can't be determined for rules. Set a prefix with a '# gazelle:prefix' comment or with -go_prefix on the command line", pkg.dir)
}
pkg.importPath = inferImportPath(gc, pkg.rel)
if pkg.rel == gc.prefixRel {
pkg.importPath = gc.prefix
} else {
fromPrefixRel := strings.TrimPrefix(pkg.rel, gc.prefixRel+"/")
pkg.importPath = path.Join(gc.prefix, fromPrefixRel)
}
return nil
}
func inferImportPath(gc *goConfig, rel string) string {
if rel == gc.prefixRel {
return gc.prefix
} else {
fromPrefixRel := strings.TrimPrefix(rel, gc.prefixRel+"/")
return path.Join(gc.prefix, fromPrefixRel)
}
}
func goProtoPackageName(pkg proto.Package) string {
if value, ok := pkg.Options["go_package"]; ok {
if strings.LastIndexByte(value, '/') == -1 {
return value
} else {
if i := strings.LastIndexByte(value, ';'); i != -1 {
return value[i+1:]
} else {
return path.Base(value)
}
}
}
return strings.Replace(pkg.Name, ".", "_", -1)
}
func goProtoImportPath(gc *goConfig, pkg proto.Package, rel string) string {
if value, ok := pkg.Options["go_package"]; ok {
if strings.LastIndexByte(value, '/') == -1 {
return inferImportPath(gc, rel)
} else if i := strings.LastIndexByte(value, ';'); i != -1 {
return value[:i]
} else {
return value
}
}
return inferImportPath(gc, rel)
}
func (t *goTarget) addFile(c *config.Config, info fileInfo) {
t.cgo = t.cgo || info.isCgo
add := getPlatformStringsAddFunction(c, info, nil)
add(&t.sources, info.name)
add(&t.imports, info.imports...)
for _, copts := range info.copts {
optAdd := add
if len(copts.tags) > 0 {
optAdd = getPlatformStringsAddFunction(c, info, copts.tags)
}
optAdd(&t.copts, copts.opts)
}
for _, clinkopts := range info.clinkopts {
optAdd := add
if len(clinkopts.tags) > 0 {
optAdd = getPlatformStringsAddFunction(c, info, clinkopts.tags)
}
optAdd(&t.clinkopts, clinkopts.opts)
}
}
func protoTargetFromProtoPackage(name string, pkg proto.Package) protoTarget {
target := protoTarget{name: name}
for f := range pkg.Files {
target.sources.addGenericString(f)
}
for i := range pkg.Imports {
target.imports.addGenericString(i)
}
target.hasServices = pkg.HasServices
return target
}
func (t *protoTarget) addFile(c *config.Config, info fileInfo) {
t.sources.addGenericString(info.name)
for _, imp := range info.imports {
t.imports.addGenericString(imp)
}
t.hasServices = t.hasServices || info.hasServices
}
// getPlatformStringsAddFunction returns a function used to add strings to
// a *platformStringsBuilder under the same set of constraints. This is a
// performance optimization to avoid evaluating constraints repeatedly.
func getPlatformStringsAddFunction(c *config.Config, info fileInfo, cgoTags tagLine) func(sb *platformStringsBuilder, ss ...string) {
isOSSpecific, isArchSpecific := isOSArchSpecific(info, cgoTags)
switch {
case !isOSSpecific && !isArchSpecific:
if checkConstraints(c, "", "", info.goos, info.goarch, info.tags, cgoTags) {
return func(sb *platformStringsBuilder, ss ...string) {
for _, s := range ss {
sb.addGenericString(s)
}
}
}
case isOSSpecific && !isArchSpecific:
var osMatch []string
for _, os := range rule.KnownOSs {
if checkConstraints(c, os, "", info.goos, info.goarch, info.tags, cgoTags) {
osMatch = append(osMatch, os)
}
}
if len(osMatch) > 0 {
return func(sb *platformStringsBuilder, ss ...string) {
for _, s := range ss {
sb.addOSString(s, osMatch)
}
}
}
case !isOSSpecific && isArchSpecific:
var archMatch []string
for _, arch := range rule.KnownArchs {
if checkConstraints(c, "", arch, info.goos, info.goarch, info.tags, cgoTags) {
archMatch = append(archMatch, arch)
}
}
if len(archMatch) > 0 {
return func(sb *platformStringsBuilder, ss ...string) {
for _, s := range ss {
sb.addArchString(s, archMatch)
}
}
}
default:
var platformMatch []rule.Platform
for _, platform := range rule.KnownPlatforms {
if checkConstraints(c, platform.OS, platform.Arch, info.goos, info.goarch, info.tags, cgoTags) {
platformMatch = append(platformMatch, platform)
}
}
if len(platformMatch) > 0 {
return func(sb *platformStringsBuilder, ss ...string) {
for _, s := range ss {
sb.addPlatformString(s, platformMatch)
}
}
}
}
return func(_ *platformStringsBuilder, _ ...string) {}
}
func (sb *platformStringsBuilder) isEmpty() bool {
return sb.strs == nil
}
func (sb *platformStringsBuilder) hasGo() bool {
for s := range sb.strs {
if strings.HasSuffix(s, ".go") {
return true
}
}
return false
}
func (sb *platformStringsBuilder) addGenericString(s string) {
if sb.strs == nil {
sb.strs = make(map[string]platformStringInfo)
}
sb.strs[s] = platformStringInfo{set: genericSet}
}
func (sb *platformStringsBuilder) addOSString(s string, oss []string) {
if sb.strs == nil {
sb.strs = make(map[string]platformStringInfo)
}
si, ok := sb.strs[s]
if !ok {
si.set = osSet
si.oss = make(map[string]bool)
}
switch si.set {
case genericSet:
return
case osSet:
for _, os := range oss {
si.oss[os] = true
}
default:
si.convertToPlatforms()
for _, os := range oss {
for _, arch := range rule.KnownOSArchs[os] {
si.platforms[rule.Platform{OS: os, Arch: arch}] = true
}
}
}
sb.strs[s] = si
}
func (sb *platformStringsBuilder) addArchString(s string, archs []string) {
if sb.strs == nil {
sb.strs = make(map[string]platformStringInfo)
}
si, ok := sb.strs[s]
if !ok {
si.set = archSet
si.archs = make(map[string]bool)
}
switch si.set {
case genericSet:
return
case archSet:
for _, arch := range archs {
si.archs[arch] = true
}
default:
si.convertToPlatforms()
for _, arch := range archs {
for _, os := range rule.KnownArchOSs[arch] {
si.platforms[rule.Platform{OS: os, Arch: arch}] = true
}
}
}
sb.strs[s] = si
}
func (sb *platformStringsBuilder) addPlatformString(s string, platforms []rule.Platform) {
if sb.strs == nil {
sb.strs = make(map[string]platformStringInfo)
}
si, ok := sb.strs[s]
if !ok {
si.set = platformSet
si.platforms = make(map[rule.Platform]bool)
}
switch si.set {
case genericSet:
return
default:
si.convertToPlatforms()
for _, p := range platforms {
si.platforms[p] = true
}
}
sb.strs[s] = si
}
func (sb *platformStringsBuilder) build() rule.PlatformStrings {
var ps rule.PlatformStrings
for s, si := range sb.strs {
switch si.set {
case genericSet:
ps.Generic = append(ps.Generic, s)
case osSet:
if ps.OS == nil {
ps.OS = make(map[string][]string)
}
for os := range si.oss {
ps.OS[os] = append(ps.OS[os], s)
}
case archSet:
if ps.Arch == nil {
ps.Arch = make(map[string][]string)
}
for arch := range si.archs {
ps.Arch[arch] = append(ps.Arch[arch], s)
}
case platformSet:
if ps.Platform == nil {
ps.Platform = make(map[rule.Platform][]string)
}
for p := range si.platforms {
ps.Platform[p] = append(ps.Platform[p], s)
}
}
}
sort.Strings(ps.Generic)
if ps.OS != nil {
for _, ss := range ps.OS {
sort.Strings(ss)
}
}
if ps.Arch != nil {
for _, ss := range ps.Arch {
sort.Strings(ss)
}
}
if ps.Platform != nil {
for _, ss := range ps.Platform {
sort.Strings(ss)
}
}
return ps
}
func (sb *platformStringsBuilder) buildFlat() []string {
strs := make([]string, 0, len(sb.strs))
for s := range sb.strs {
strs = append(strs, s)
}
sort.Strings(strs)
return strs
}
func (si *platformStringInfo) convertToPlatforms() {
switch si.set {
case genericSet:
log.Panic("cannot convert generic string to platforms")
case platformSet:
return
case osSet:
si.set = platformSet
si.platforms = make(map[rule.Platform]bool)
for os := range si.oss {
for _, arch := range rule.KnownOSArchs[os] {
si.platforms[rule.Platform{OS: os, Arch: arch}] = true
}
}
si.oss = nil
case archSet:
si.set = platformSet
si.platforms = make(map[rule.Platform]bool)
for arch := range si.archs {
for _, os := range rule.KnownArchOSs[arch] {
si.platforms[rule.Platform{OS: os, Arch: arch}] = true
}
}
si.archs = nil
}
}

View File

@@ -1,306 +0,0 @@
/* Copyright 2018 The Bazel Authors. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package golang
import (
"errors"
"fmt"
"go/build"
"log"
"path"
"strings"
"github.com/bazelbuild/bazel-gazelle/internal/config"
"github.com/bazelbuild/bazel-gazelle/internal/label"
"github.com/bazelbuild/bazel-gazelle/internal/language/proto"
"github.com/bazelbuild/bazel-gazelle/internal/pathtools"
"github.com/bazelbuild/bazel-gazelle/internal/repos"
"github.com/bazelbuild/bazel-gazelle/internal/resolve"
"github.com/bazelbuild/bazel-gazelle/internal/rule"
)
func (_ *goLang) Imports(_ *config.Config, r *rule.Rule, f *rule.File) []resolve.ImportSpec {
if !isGoLibrary(r.Kind()) {
return nil
}
if importPath := r.AttrString("importpath"); importPath == "" {
return []resolve.ImportSpec{}
} else {
return []resolve.ImportSpec{{goName, importPath}}
}
}
func (_ *goLang) Embeds(r *rule.Rule, from label.Label) []label.Label {
embedStrings := r.AttrStrings("embed")
if isGoProtoLibrary(r.Kind()) {
embedStrings = append(embedStrings, r.AttrString("proto"))
}
embedLabels := make([]label.Label, 0, len(embedStrings))
for _, s := range embedStrings {
l, err := label.Parse(s)
if err != nil {
continue
}
l = l.Abs(from.Repo, from.Pkg)
embedLabels = append(embedLabels, l)
}
return embedLabels
}
func (gl *goLang) Resolve(c *config.Config, ix *resolve.RuleIndex, rc *repos.RemoteCache, r *rule.Rule, from label.Label) {
importsRaw := r.PrivateAttr(config.GazelleImportsKey)
if importsRaw == nil {
// may not be set in tests.
return
}
imports := importsRaw.(rule.PlatformStrings)
r.DelAttr("deps")
resolve := resolveGo
if r.Kind() == "go_proto_library" {
resolve = resolveProto
}
deps, errs := imports.Map(func(imp string) (string, error) {
l, err := resolve(c, ix, rc, r, imp, from)
if err == skipImportError {
return "", nil
} else if err != nil {
return "", err
}
for _, embed := range gl.Embeds(r, from) {
if embed.Equal(l) {
return "", nil
}
}
l = l.Rel(from.Repo, from.Pkg)
return l.String(), nil
})
for _, err := range errs {
log.Print(err)
}
if !deps.IsEmpty() {
r.SetAttr("deps", deps)
}
}
var (
skipImportError = errors.New("std or self import")
notFoundError = errors.New("rule not found")
)
func resolveGo(c *config.Config, ix *resolve.RuleIndex, rc *repos.RemoteCache, r *rule.Rule, imp string, from label.Label) (label.Label, error) {
gc := getGoConfig(c)
pc := proto.GetProtoConfig(c)
if build.IsLocalImport(imp) {
cleanRel := path.Clean(path.Join(from.Pkg, imp))
if build.IsLocalImport(cleanRel) {
return label.NoLabel, fmt.Errorf("relative import path %q from %q points outside of repository", imp, from.Pkg)
}
imp = path.Join(gc.prefix, cleanRel)
}
if isStandard(imp) {
return label.NoLabel, skipImportError
}
if pc.Mode.ShouldUseKnownImports() {
// These are commonly used libraries that depend on Well Known Types.
// They depend on the generated versions of these protos to avoid conflicts.
// However, since protoc-gen-go depends on these libraries, we generate
// its rules in disable_global mode (to avoid cyclic dependency), so the
// "go_default_library" versions of these libraries depend on the
// pre-generated versions of the proto libraries.
switch imp {
case "github.com/golang/protobuf/jsonpb":
return label.New("com_github_golang_protobuf", "jsonpb", "go_default_library_gen"), nil
case "github.com/golang/protobuf/descriptor":
return label.New("com_github_golang_protobuf", "descriptor", "go_default_library_gen"), nil
case "github.com/golang/protobuf/ptypes":
return label.New("com_github_golang_protobuf", "ptypes", "go_default_library_gen"), nil
}
if l, ok := knownGoProtoImports[imp]; ok {
return l, nil
}
}
if l, err := resolveWithIndexGo(ix, imp, from); err == nil || err == skipImportError {
return l, err
} else if err != notFoundError {
return label.NoLabel, err
}
if pathtools.HasPrefix(imp, gc.prefix) {
pkg := path.Join(gc.prefixRel, pathtools.TrimPrefix(imp, gc.prefix))
return label.New("", pkg, config.DefaultLibName), nil
}
if gc.depMode == externalMode {
return resolveExternal(rc, imp)
} else {
return resolveVendored(rc, imp)
}
}
// isStandard returns whether a package is in the standard library.
func isStandard(imp string) bool {
return stdPackages[imp]
}
func resolveWithIndexGo(ix *resolve.RuleIndex, imp string, from label.Label) (label.Label, error) {
matches := ix.FindRulesByImport(resolve.ImportSpec{Lang: "go", Imp: imp}, "go")
var bestMatch resolve.FindResult
var bestMatchIsVendored bool
var bestMatchVendorRoot string
var matchError error
for _, m := range matches {
// Apply vendoring logic for Go libraries. A library in a vendor directory
// is only visible in the parent tree. Vendored libraries supercede
// non-vendored libraries, and libraries closer to from.Pkg supercede
// those further up the tree.
isVendored := false
vendorRoot := ""
parts := strings.Split(m.Label.Pkg, "/")
for i := len(parts) - 1; i >= 0; i-- {
if parts[i] == "vendor" {
isVendored = true
vendorRoot = strings.Join(parts[:i], "/")
break
}
}
if isVendored {
}
if isVendored && !label.New(m.Label.Repo, vendorRoot, "").Contains(from) {
// vendor directory not visible
continue
}
if bestMatch.Label.Equal(label.NoLabel) || isVendored && (!bestMatchIsVendored || len(vendorRoot) > len(bestMatchVendorRoot)) {
// Current match is better
bestMatch = m
bestMatchIsVendored = isVendored
bestMatchVendorRoot = vendorRoot
matchError = nil
} else if (!isVendored && bestMatchIsVendored) || (isVendored && len(vendorRoot) < len(bestMatchVendorRoot)) {
// Current match is worse
} else {
// Match is ambiguous
matchError = fmt.Errorf("multiple rules (%s and %s) may be imported with %q from %s", bestMatch.Label, m.Label, imp, from)
}
}
if matchError != nil {
return label.NoLabel, matchError
}
if bestMatch.Label.Equal(label.NoLabel) {
return label.NoLabel, notFoundError
}
if bestMatch.IsSelfImport(from) {
return label.NoLabel, skipImportError
}
return bestMatch.Label, nil
}
func resolveExternal(rc *repos.RemoteCache, imp string) (label.Label, error) {
prefix, repo, err := rc.Root(imp)
if err != nil {
return label.NoLabel, err
}
var pkg string
if imp != prefix {
pkg = pathtools.TrimPrefix(imp, prefix)
}
return label.New(repo, pkg, config.DefaultLibName), nil
}
func resolveVendored(rc *repos.RemoteCache, imp string) (label.Label, error) {
return label.New("", path.Join("vendor", imp), config.DefaultLibName), nil
}
func resolveProto(c *config.Config, ix *resolve.RuleIndex, rc *repos.RemoteCache, r *rule.Rule, imp string, from label.Label) (label.Label, error) {
pc := proto.GetProtoConfig(c)
if wellKnownProtos[imp] {
return label.NoLabel, skipImportError
}
if l, ok := knownProtoImports[imp]; ok && pc.Mode.ShouldUseKnownImports() {
if l.Equal(from) {
return label.NoLabel, skipImportError
} else {
return l, nil
}
}
if l, err := resolveWithIndexProto(ix, imp, from); err == nil || err == skipImportError {
return l, err
} else if err != notFoundError {
return label.NoLabel, err
}
// As a fallback, guess the label based on the proto file name. We assume
// all proto files in a directory belong to the same package, and the
// package name matches the directory base name. We also assume that protos
// in the vendor directory must refer to something else in vendor.
rel := path.Dir(imp)
if rel == "." {
rel = ""
}
if from.Pkg == "vendor" || strings.HasPrefix(from.Pkg, "vendor/") {
rel = path.Join("vendor", rel)
}
return label.New("", rel, config.DefaultLibName), nil
}
// wellKnownProtos is the set of proto sets for which we don't need to add
// an explicit dependency in go_proto_library.
// TODO(jayconrod): generate from
// @io_bazel_rules_go//proto/wkt:WELL_KNOWN_TYPE_PACKAGES
var wellKnownProtos = map[string]bool{
"google/protobuf/any.proto": true,
"google/protobuf/api.proto": true,
"google/protobuf/compiler_plugin.proto": true,
"google/protobuf/descriptor.proto": true,
"google/protobuf/duration.proto": true,
"google/protobuf/empty.proto": true,
"google/protobuf/field_mask.proto": true,
"google/protobuf/source_context.proto": true,
"google/protobuf/struct.proto": true,
"google/protobuf/timestamp.proto": true,
"google/protobuf/type.proto": true,
"google/protobuf/wrappers.proto": true,
}
func resolveWithIndexProto(ix *resolve.RuleIndex, imp string, from label.Label) (label.Label, error) {
matches := ix.FindRulesByImport(resolve.ImportSpec{Lang: "proto", Imp: imp}, "go")
if len(matches) == 0 {
return label.NoLabel, notFoundError
}
if len(matches) > 1 {
return label.NoLabel, fmt.Errorf("multiple rules (%s and %s) may be imported with %q from %s", matches[0].Label, matches[1].Label, imp, from)
}
if matches[0].IsSelfImport(from) {
return label.NoLabel, skipImportError
}
return matches[0].Label, nil
}
func isGoLibrary(kind string) bool {
return kind == "go_library" || isGoProtoLibrary(kind)
}
func isGoProtoLibrary(kind string) bool {
return kind == "go_proto_library" || kind == "go_grpc_library"
}

View File

@@ -1,284 +0,0 @@
/* Copyright 2017 The Bazel Authors. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Generated by gen_std_package_list.go
// DO NOT EDIT
package golang
var stdPackages = map[string]bool{
"archive/tar": true,
"archive/zip": true,
"bufio": true,
"bytes": true,
"cmd/addr2line": true,
"cmd/api": true,
"cmd/asm": true,
"cmd/asm/internal/arch": true,
"cmd/asm/internal/asm": true,
"cmd/asm/internal/flags": true,
"cmd/asm/internal/lex": true,
"cmd/buildid": true,
"cmd/cgo": true,
"cmd/compile": true,
"cmd/compile/internal/amd64": true,
"cmd/compile/internal/arm": true,
"cmd/compile/internal/arm64": true,
"cmd/compile/internal/gc": true,
"cmd/compile/internal/mips": true,
"cmd/compile/internal/mips64": true,
"cmd/compile/internal/ppc64": true,
"cmd/compile/internal/s390x": true,
"cmd/compile/internal/ssa": true,
"cmd/compile/internal/syntax": true,
"cmd/compile/internal/test": true,
"cmd/compile/internal/types": true,
"cmd/compile/internal/x86": true,
"cmd/cover": true,
"cmd/dist": true,
"cmd/doc": true,
"cmd/fix": true,
"cmd/go": true,
"cmd/go/internal/base": true,
"cmd/go/internal/bug": true,
"cmd/go/internal/cache": true,
"cmd/go/internal/cfg": true,
"cmd/go/internal/clean": true,
"cmd/go/internal/cmdflag": true,
"cmd/go/internal/doc": true,
"cmd/go/internal/envcmd": true,
"cmd/go/internal/fix": true,
"cmd/go/internal/fmtcmd": true,
"cmd/go/internal/generate": true,
"cmd/go/internal/get": true,
"cmd/go/internal/help": true,
"cmd/go/internal/list": true,
"cmd/go/internal/load": true,
"cmd/go/internal/run": true,
"cmd/go/internal/str": true,
"cmd/go/internal/test": true,
"cmd/go/internal/tool": true,
"cmd/go/internal/version": true,
"cmd/go/internal/vet": true,
"cmd/go/internal/web": true,
"cmd/go/internal/work": true,
"cmd/gofmt": true,
"cmd/internal/bio": true,
"cmd/internal/browser": true,
"cmd/internal/buildid": true,
"cmd/internal/dwarf": true,
"cmd/internal/edit": true,
"cmd/internal/gcprog": true,
"cmd/internal/goobj": true,
"cmd/internal/obj": true,
"cmd/internal/obj/arm": true,
"cmd/internal/obj/arm64": true,
"cmd/internal/obj/mips": true,
"cmd/internal/obj/ppc64": true,
"cmd/internal/obj/s390x": true,
"cmd/internal/obj/x86": true,
"cmd/internal/objabi": true,
"cmd/internal/objfile": true,
"cmd/internal/src": true,
"cmd/internal/sys": true,
"cmd/internal/test2json": true,
"cmd/link": true,
"cmd/link/internal/amd64": true,
"cmd/link/internal/arm": true,
"cmd/link/internal/arm64": true,
"cmd/link/internal/ld": true,
"cmd/link/internal/loadelf": true,
"cmd/link/internal/loadmacho": true,
"cmd/link/internal/loadpe": true,
"cmd/link/internal/mips": true,
"cmd/link/internal/mips64": true,
"cmd/link/internal/objfile": true,
"cmd/link/internal/ppc64": true,
"cmd/link/internal/s390x": true,
"cmd/link/internal/sym": true,
"cmd/link/internal/x86": true,
"cmd/nm": true,
"cmd/objdump": true,
"cmd/pack": true,
"cmd/pprof": true,
"cmd/test2json": true,
"cmd/trace": true,
"cmd/vet": true,
"cmd/vet/internal/cfg": true,
"cmd/vet/internal/whitelist": true,
"compress/bzip2": true,
"compress/flate": true,
"compress/gzip": true,
"compress/lzw": true,
"compress/zlib": true,
"container/heap": true,
"container/list": true,
"container/ring": true,
"context": true,
"crypto": true,
"crypto/aes": true,
"crypto/cipher": true,
"crypto/des": true,
"crypto/dsa": true,
"crypto/ecdsa": true,
"crypto/elliptic": true,
"crypto/hmac": true,
"crypto/internal/cipherhw": true,
"crypto/md5": true,
"crypto/rand": true,
"crypto/rc4": true,
"crypto/rsa": true,
"crypto/sha1": true,
"crypto/sha256": true,
"crypto/sha512": true,
"crypto/subtle": true,
"crypto/tls": true,
"crypto/x509": true,
"crypto/x509/pkix": true,
"database/sql": true,
"database/sql/driver": true,
"debug/dwarf": true,
"debug/elf": true,
"debug/gosym": true,
"debug/macho": true,
"debug/pe": true,
"debug/plan9obj": true,
"encoding": true,
"encoding/ascii85": true,
"encoding/asn1": true,
"encoding/base32": true,
"encoding/base64": true,
"encoding/binary": true,
"encoding/csv": true,
"encoding/gob": true,
"encoding/hex": true,
"encoding/json": true,
"encoding/pem": true,
"encoding/xml": true,
"errors": true,
"expvar": true,
"flag": true,
"fmt": true,
"go/ast": true,
"go/build": true,
"go/constant": true,
"go/doc": true,
"go/format": true,
"go/importer": true,
"go/internal/gccgoimporter": true,
"go/internal/gcimporter": true,
"go/internal/srcimporter": true,
"go/parser": true,
"go/printer": true,
"go/scanner": true,
"go/token": true,
"go/types": true,
"hash": true,
"hash/adler32": true,
"hash/crc32": true,
"hash/crc64": true,
"hash/fnv": true,
"html": true,
"html/template": true,
"image": true,
"image/color": true,
"image/color/palette": true,
"image/draw": true,
"image/gif": true,
"image/internal/imageutil": true,
"image/jpeg": true,
"image/png": true,
"index/suffixarray": true,
"internal/cpu": true,
"internal/nettrace": true,
"internal/poll": true,
"internal/race": true,
"internal/singleflight": true,
"internal/syscall/windows": true,
"internal/syscall/windows/registry": true,
"internal/syscall/windows/sysdll": true,
"internal/testenv": true,
"internal/testlog": true,
"internal/trace": true,
"io": true,
"io/ioutil": true,
"log": true,
"log/syslog": true,
"math": true,
"math/big": true,
"math/bits": true,
"math/cmplx": true,
"math/rand": true,
"mime": true,
"mime/multipart": true,
"mime/quotedprintable": true,
"net": true,
"net/http": true,
"net/http/cgi": true,
"net/http/cookiejar": true,
"net/http/fcgi": true,
"net/http/httptest": true,
"net/http/httptrace": true,
"net/http/httputil": true,
"net/http/internal": true,
"net/http/pprof": true,
"net/internal/socktest": true,
"net/mail": true,
"net/rpc": true,
"net/rpc/jsonrpc": true,
"net/smtp": true,
"net/textproto": true,
"net/url": true,
"os": true,
"os/exec": true,
"os/signal": true,
"os/signal/internal/pty": true,
"os/user": true,
"path": true,
"path/filepath": true,
"plugin": true,
"reflect": true,
"regexp": true,
"regexp/syntax": true,
"runtime": true,
"runtime/cgo": true,
"runtime/debug": true,
"runtime/internal/atomic": true,
"runtime/internal/sys": true,
"runtime/pprof": true,
"runtime/pprof/internal/profile": true,
"runtime/race": true,
"runtime/trace": true,
"sort": true,
"strconv": true,
"strings": true,
"sync": true,
"sync/atomic": true,
"syscall": true,
"testing": true,
"testing/internal/testdeps": true,
"testing/iotest": true,
"testing/quick": true,
"text/scanner": true,
"text/tabwriter": true,
"text/template": true,
"text/template/parse": true,
"time": true,
"unicode": true,
"unicode/utf16": true,
"unicode/utf8": true,
"unsafe": true,
}

View File

@@ -1,96 +0,0 @@
/* Copyright 2018 The Bazel Authors. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package language
import (
"github.com/bazelbuild/bazel-gazelle/internal/config"
"github.com/bazelbuild/bazel-gazelle/internal/resolve"
"github.com/bazelbuild/bazel-gazelle/internal/rule"
)
// Language describes an extension for Gazelle that provides support for
// a set of Bazel rules.
//
// Languages are used primarily by the fix and update commands. The order
// in which languages are used matters, since languages may depend on
// one another. For example, go depends on proto, since go_proto_libraries
// are generated from metadata stored in proto_libraries.
//
// A single instance of Language is created for each fix / update run. Some
// state may be stored in this instance, but stateless behavior is encouraged,
// especially since some operations may be concurrent in the future.
//
// Tasks languages are used for
//
// * Configuration (embedded interface config.Configurer). Languages may
// define command line flags and alter the configuration in a directory
// based on directives in build files.
//
// * Fixing deprecated usage of rules in build files.
//
// * Generating rules from source files in a directory.
//
// * Resolving library imports (embedded interface resolve.Resolver). For
// example, import strings like "github.com/foo/bar" in Go can be resolved
// into Bazel labels like "@com_github_foo_bar//:go_default_library".
//
// Tasks languages support
//
// * Generating load statements: languages list files and symbols that may
// be loaded.
//
// * Merging generated rules into existing rules: languages provide metadata
// that helps with rule matching, merging, and deletion.
type Language interface {
config.Configurer
resolve.Resolver
// Kinds returns a map of maps rule names (kinds) and information on how to
// match and merge attributes that may be found in rules of those kinds. All
// kinds of rules generated for this language may be found here.
Kinds() map[string]rule.KindInfo
// Loads returns .bzl files and symbols they define. Every rule generated by
// GenerateRules, now or in the past, should be loadable from one of these
// files.
Loads() []rule.LoadInfo
// GenerateRules extracts build metadata from source files in a directory.
// GenerateRules is called in each directory where an update is requested
// in depth-first post-order.
//
// c is the configuration for the current directory.
// dir is the absolute path to the directory to scan.
// rel is the relative path to the directory from the repository root.
// f is the build file. It may be nil. It should not be modified.
// subdirs is a list of subdirectory names.
// regularFiles is a list of normal files in the directory.
// genFiles is a list of generated files, found in outputs of rules.
// otherEmpty and otherGen are lists of empty and generated rules created
// by other languages processed before this language.
//
// empty is a list of empty rules that may be deleted after merge.
// gen is a list of generated rules that may be updated or added.
//
// Any non-fatal errors this function encounters should be logged using
// log.Print.
GenerateRules(c *config.Config, dir, rel string, f *rule.File, subdirs, regularFiles, genFiles []string, otherEmpty, otherGen []*rule.Rule) (empty, gen []*rule.Rule)
// Fix repairs deprecated usage of language-specific rules in f. This is
// called before the file is indexed. Unless c.ShouldFix is true, fixes
// that delete or rename rules should not be performed.
Fix(c *config.Config, f *rule.File)
}

View File

@@ -1,42 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"config.go",
"constants.go",
"fileinfo.go",
"fix.go",
"generate.go",
"kinds.go",
"known_imports.go",
"lang.go",
"package.go",
"resolve.go",
],
importmap = "sigs.k8s.io/kind/vendor/github.com/bazelbuild/bazel-gazelle/internal/language/proto",
importpath = "github.com/bazelbuild/bazel-gazelle/internal/language/proto",
visibility = ["//vendor/github.com/bazelbuild/bazel-gazelle:__subpackages__"],
deps = [
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/config:go_default_library",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/label:go_default_library",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/language:go_default_library",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/repos:go_default_library",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/resolve:go_default_library",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/rule:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -1,250 +0,0 @@
/* Copyright 2018 The Bazel Authors. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package proto
import (
"flag"
"fmt"
"log"
"path"
"github.com/bazelbuild/bazel-gazelle/internal/config"
"github.com/bazelbuild/bazel-gazelle/internal/rule"
)
// ProtoConfig contains configuration values related to protos.
//
// This type is public because other languages need to generate rules based
// on protos, so this configuration may be relevant to them.
type ProtoConfig struct {
// Mode determines how rules are generated for protos.
Mode Mode
// ModeExplicit indicates whether the proto mode was set explicitly.
ModeExplicit bool
// GoPrefix is the current Go prefix (the Go extension may set this in the
// root directory only). Used to generate proto rule names in the root
// directory when there are no proto files or the proto package name
// can't be determined.
// TODO(jayconrod): deprecate and remove Go-specific behavior.
GoPrefix string
// groupOption is an option name that Gazelle will use to group .proto
// files into proto_library rules. If unset, the proto package name is used.
groupOption string
}
func GetProtoConfig(c *config.Config) *ProtoConfig {
return c.Exts[protoName].(*ProtoConfig)
}
// Mode determines how proto rules are generated.
type Mode int
const (
// DefaultMode generates proto_library rules. Other languages should generate
// library rules based on these (e.g., go_proto_library) and should ignore
// checked-in generated files (e.g., .pb.go files) when there is a .proto
// file with a similar name.
DefaultMode Mode = iota
// DisableMode ignores .proto files and generates empty proto_library rules.
// Checked-in generated files (e.g., .pb.go files) should be treated as
// normal sources.
DisableMode
// DisableGlobalMode is similar to DisableMode, but it also prevents
// the use of special cases in dependency resolution for well known types
// and Google APIs.
DisableGlobalMode
// LegacyMode generates filegroups for .proto files if .pb.go files are
// present in the same directory.
LegacyMode
// PackageMode generates a proto_library for each set of .proto files with
// the same package name in each directory.
PackageMode
)
func ModeFromString(s string) (Mode, error) {
switch s {
case "default":
return DefaultMode, nil
case "disable":
return DisableMode, nil
case "disable_global":
return DisableGlobalMode, nil
case "legacy":
return LegacyMode, nil
case "package":
return PackageMode, nil
default:
return 0, fmt.Errorf("unrecognized proto mode: %q", s)
}
}
func (m Mode) String() string {
switch m {
case DefaultMode:
return "default"
case DisableMode:
return "disable"
case DisableGlobalMode:
return "disable_global"
case LegacyMode:
return "legacy"
case PackageMode:
return "package"
default:
log.Panicf("unknown mode %d", m)
return ""
}
}
func (m Mode) ShouldGenerateRules() bool {
switch m {
case DisableMode, DisableGlobalMode, LegacyMode:
return false
default:
return true
}
}
func (m Mode) ShouldIncludePregeneratedFiles() bool {
switch m {
case DisableMode, DisableGlobalMode, LegacyMode:
return true
default:
return false
}
}
func (m Mode) ShouldUseKnownImports() bool {
return m != DisableGlobalMode
}
type modeFlag struct {
mode *Mode
}
func (f *modeFlag) Set(value string) error {
if mode, err := ModeFromString(value); err != nil {
return err
} else {
*f.mode = mode
return nil
}
}
func (f *modeFlag) String() string {
var mode Mode
if f != nil && f.mode != nil {
mode = *f.mode
}
return mode.String()
}
func (_ *protoLang) RegisterFlags(fs *flag.FlagSet, cmd string, c *config.Config) {
pc := &ProtoConfig{}
c.Exts[protoName] = pc
// Note: the -proto flag does not set the ModeExplicit flag. We want to
// be able to switch to DisableMode in vendor directories, even when
// this is set for compatibility with older versions.
fs.Var(&modeFlag{&pc.Mode}, "proto", "default: generates a proto_library rule for one package\n\tpackage: generates a proto_library rule for for each package\n\tdisable: does not touch proto rules\n\tdisable_global: does not touch proto rules and does not use special cases for protos in dependency resolution")
fs.StringVar(&pc.groupOption, "proto_group", "", "option name used to group .proto files into proto_library rules")
}
func (_ *protoLang) CheckFlags(fs *flag.FlagSet, c *config.Config) error {
return nil
}
func (_ *protoLang) KnownDirectives() []string {
return []string{"proto", "proto_group"}
}
func (_ *protoLang) Configure(c *config.Config, rel string, f *rule.File) {
pc := &ProtoConfig{}
*pc = *GetProtoConfig(c)
c.Exts[protoName] = pc
if f != nil {
for _, d := range f.Directives {
switch d.Key {
case "proto":
mode, err := ModeFromString(d.Value)
if err != nil {
log.Print(err)
continue
}
pc.Mode = mode
pc.ModeExplicit = true
case "proto_group":
pc.groupOption = d.Value
}
}
}
inferProtoMode(c, rel, f)
}
// inferProtoMode sets ProtoConfig.Mode based on the directory name and the
// contents of f. If the proto mode is set explicitly, this function does not
// change it. If this is a vendor directory, or go_proto_library is loaded from
// another file, proto rule generation is disabled.
//
// TODO(jayconrod): this logic is archaic, now that rules are generated by
// separate language extensions. Proto rule generation should be independent
// from Go.
func inferProtoMode(c *config.Config, rel string, f *rule.File) {
pc := GetProtoConfig(c)
if pc.Mode != DefaultMode || pc.ModeExplicit {
return
}
if pc.GoPrefix == wellKnownTypesGoPrefix {
pc.Mode = LegacyMode
return
}
if path.Base(rel) == "vendor" {
pc.Mode = DisableMode
return
}
if f == nil {
return
}
mode := DefaultMode
outer:
for _, l := range f.Loads {
name := l.Name()
if name == "@io_bazel_rules_go//proto:def.bzl" {
break
}
if name == "@io_bazel_rules_go//proto:go_proto_library.bzl" {
mode = LegacyMode
break
}
for _, sym := range l.Symbols() {
if sym == "go_proto_library" {
mode = DisableMode
break outer
}
}
}
if mode == DefaultMode || pc.Mode == mode || c.ShouldFix && mode == LegacyMode {
return
}
pc.Mode = mode
}

View File

@@ -1,27 +0,0 @@
/* Copyright 2018 The Bazel Authors. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package proto
const (
// PackageInfoKey is the name of a private attribute set on generated
// proto_library rules. This attribute contains a Package record which
// describes the library and its sources.
PackageKey = "_package"
// wellKnownTypesGoPrefix is the import path for the Go repository containing
// pre-generated code for the Well Known Types.
wellKnownTypesGoPrefix = "github.com/golang/protobuf"
)

View File

@@ -1,138 +0,0 @@
/* Copyright 2018 The Bazel Authors. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package proto
import (
"bytes"
"io/ioutil"
"log"
"path/filepath"
"regexp"
"sort"
"strconv"
"strings"
)
// FileInfo contains metadata extracted from a .proto file.
type FileInfo struct {
Path, Name string
PackageName string
Options []Option
Imports []string
HasServices bool
}
// Option represents a top-level option statement in a .proto file. Only
// string options are supported for now.
type Option struct {
Key, Value string
}
var protoRe = buildProtoRegexp()
func protoFileInfo(dir, name string) FileInfo {
info := FileInfo{
Path: filepath.Join(dir, name),
Name: name,
}
content, err := ioutil.ReadFile(info.Path)
if err != nil {
log.Printf("%s: error reading proto file: %v", info.Path, err)
return info
}
for _, match := range protoRe.FindAllSubmatch(content, -1) {
switch {
case match[importSubexpIndex] != nil:
imp := unquoteProtoString(match[importSubexpIndex])
info.Imports = append(info.Imports, imp)
case match[packageSubexpIndex] != nil:
pkg := string(match[packageSubexpIndex])
if info.PackageName == "" {
info.PackageName = pkg
}
case match[optkeySubexpIndex] != nil:
key := string(match[optkeySubexpIndex])
value := unquoteProtoString(match[optvalSubexpIndex])
info.Options = append(info.Options, Option{key, value})
case match[serviceSubexpIndex] != nil:
info.HasServices = true
default:
// Comment matched. Nothing to extract.
}
}
sort.Strings(info.Imports)
return info
}
const (
importSubexpIndex = 1
packageSubexpIndex = 2
optkeySubexpIndex = 3
optvalSubexpIndex = 4
serviceSubexpIndex = 5
)
// Based on https://developers.google.com/protocol-buffers/docs/reference/proto3-spec
func buildProtoRegexp() *regexp.Regexp {
hexEscape := `\\[xX][0-9a-fA-f]{2}`
octEscape := `\\[0-7]{3}`
charEscape := `\\[abfnrtv'"\\]`
charValue := strings.Join([]string{hexEscape, octEscape, charEscape, "[^\x00\\'\\\"\\\\]"}, "|")
strLit := `'(?:` + charValue + `|")*'|"(?:` + charValue + `|')*"`
ident := `[A-Za-z][A-Za-z0-9_]*`
fullIdent := ident + `(?:\.` + ident + `)*`
importStmt := `\bimport\s*(?:public|weak)?\s*(?P<import>` + strLit + `)\s*;`
packageStmt := `\bpackage\s*(?P<package>` + fullIdent + `)\s*;`
optionStmt := `\boption\s*(?P<optkey>` + fullIdent + `)\s*=\s*(?P<optval>` + strLit + `)\s*;`
serviceStmt := `(?P<service>service)`
comment := `//[^\n]*`
protoReSrc := strings.Join([]string{importStmt, packageStmt, optionStmt, serviceStmt, comment}, "|")
return regexp.MustCompile(protoReSrc)
}
func unquoteProtoString(q []byte) string {
// Adjust quotes so that Unquote is happy. We need a double quoted string
// without unescaped double quote characters inside.
noQuotes := bytes.Split(q[1:len(q)-1], []byte{'"'})
if len(noQuotes) != 1 {
for i := 0; i < len(noQuotes)-1; i++ {
if len(noQuotes[i]) == 0 || noQuotes[i][len(noQuotes[i])-1] != '\\' {
noQuotes[i] = append(noQuotes[i], '\\')
}
}
q = append([]byte{'"'}, bytes.Join(noQuotes, []byte{'"'})...)
q = append(q, '"')
}
if q[0] == '\'' {
q[0] = '"'
q[len(q)-1] = '"'
}
s, err := strconv.Unquote(string(q))
if err != nil {
log.Panicf("unquoting string literal %s from proto: %v", q, err)
}
return s
}

View File

@@ -1,24 +0,0 @@
/* Copyright 2018 The Bazel Authors. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package proto
import (
"github.com/bazelbuild/bazel-gazelle/internal/config"
"github.com/bazelbuild/bazel-gazelle/internal/rule"
)
func (_ *protoLang) Fix(c *config.Config, f *rule.File) {
}

View File

@@ -1,276 +0,0 @@
/* Copyright 2018 The Bazel Authors. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package proto
import (
"fmt"
"log"
"sort"
"strings"
"github.com/bazelbuild/bazel-gazelle/internal/config"
"github.com/bazelbuild/bazel-gazelle/internal/rule"
)
func (_ *protoLang) GenerateRules(c *config.Config, dir, rel string, f *rule.File, subdirs, regularFiles, genFiles []string, otherEmpty, otherGen []*rule.Rule) (empty, gen []*rule.Rule) {
pc := GetProtoConfig(c)
if !pc.Mode.ShouldGenerateRules() {
// Don't create or delete proto rules in this mode. Any existing rules
// are likely hand-written.
return nil, nil
}
var regularProtoFiles []string
for _, name := range regularFiles {
if strings.HasSuffix(name, ".proto") {
regularProtoFiles = append(regularProtoFiles, name)
}
}
var genProtoFiles []string
for _, name := range genFiles {
if strings.HasSuffix(name, ".proto") {
genProtoFiles = append(genFiles, name)
}
}
pkgs := buildPackages(pc, dir, rel, regularProtoFiles, genProtoFiles)
shouldSetVisibility := !hasDefaultVisibility(f)
for _, pkg := range pkgs {
r := generateProto(pc, rel, pkg, shouldSetVisibility)
if r.IsEmpty(protoKinds[r.Kind()]) {
empty = append(empty, r)
} else {
gen = append(gen, r)
}
}
sort.SliceStable(gen, func(i, j int) bool {
return gen[i].Name() < gen[j].Name()
})
empty = append(empty, generateEmpty(f, regularProtoFiles, genProtoFiles)...)
return empty, gen
}
// RuleName returns a name for a proto_library derived from the given strings.
// For each string, RuleName will look for a non-empty suffix of identifier
// characters and then append "_proto" to that.
func RuleName(names ...string) string {
base := "root"
for _, name := range names {
notIdent := func(c rune) bool {
return !('A' <= c && c <= 'Z' ||
'a' <= c && c <= 'z' ||
'0' <= c && c <= '9' ||
c == '_')
}
if i := strings.LastIndexFunc(name, notIdent); i >= 0 {
name = name[i+1:]
}
if name != "" {
base = name
break
}
}
return base + "_proto"
}
// buildPackage extracts metadata from the .proto files in a directory and
// constructs possibly several packages, then selects a package to generate
// a proto_library rule for.
func buildPackages(pc *ProtoConfig, dir, rel string, protoFiles, genFiles []string) []*Package {
packageMap := make(map[string]*Package)
for _, name := range protoFiles {
info := protoFileInfo(dir, name)
key := info.PackageName
if pc.groupOption != "" {
for _, opt := range info.Options {
if opt.Key == pc.groupOption {
key = opt.Value
break
}
}
}
if packageMap[key] == nil {
packageMap[key] = newPackage(info.PackageName)
}
packageMap[key].addFile(info)
}
switch pc.Mode {
case DefaultMode:
pkg, err := selectPackage(dir, rel, packageMap)
if err != nil {
log.Print(err)
}
if pkg == nil {
return nil // empty rule created in generateEmpty
}
for _, name := range genFiles {
pkg.addGenFile(dir, name)
}
return []*Package{pkg}
case PackageMode:
pkgs := make([]*Package, 0, len(packageMap))
for _, pkg := range packageMap {
pkgs = append(pkgs, pkg)
}
return pkgs
default:
return nil
}
}
// selectPackage chooses a package to generate rules for.
func selectPackage(dir, rel string, packageMap map[string]*Package) (*Package, error) {
if len(packageMap) == 0 {
return nil, nil
}
if len(packageMap) == 1 {
for _, pkg := range packageMap {
return pkg, nil
}
}
defaultPackageName := strings.Replace(rel, "/", "_", -1)
for _, pkg := range packageMap {
if pkgName := goPackageName(pkg); pkgName != "" && pkgName == defaultPackageName {
return pkg, nil
}
}
return nil, fmt.Errorf("%s: directory contains multiple proto packages. Gazelle can only generate a proto_library for one package.", dir)
}
// goPackageName guesses the identifier in package declarations at the top of
// the .pb.go files that will be generated for this package. "" is returned
// if the package name cannot be determined.
//
// TODO(jayconrod): remove all Go-specific functionality. This is here
// temporarily for compatibility.
func goPackageName(pkg *Package) string {
if opt, ok := pkg.Options["go_package"]; ok {
if i := strings.IndexByte(opt, ';'); i >= 0 {
return opt[i+1:]
} else if i := strings.LastIndexByte(opt, '/'); i >= 0 {
return opt[i+1:]
} else {
return opt
}
}
if pkg.Name != "" {
return strings.Replace(pkg.Name, ".", "_", -1)
}
if len(pkg.Files) == 1 {
for s := range pkg.Files {
return strings.TrimSuffix(s, ".proto")
}
}
return ""
}
// generateProto creates a new proto_library rule for a package. The rule may
// be empty if there are no sources.
func generateProto(pc *ProtoConfig, rel string, pkg *Package, shouldSetVisibility bool) *rule.Rule {
var name string
if pc.Mode == DefaultMode {
name = RuleName(goPackageName(pkg), pc.GoPrefix, rel)
} else {
name = RuleName(pkg.Options[pc.groupOption], pkg.Name, rel)
}
r := rule.NewRule("proto_library", name)
srcs := make([]string, 0, len(pkg.Files))
for f := range pkg.Files {
srcs = append(srcs, f)
}
sort.Strings(srcs)
if len(srcs) > 0 {
r.SetAttr("srcs", srcs)
}
r.SetPrivateAttr(PackageKey, *pkg)
imports := make([]string, 0, len(pkg.Imports))
for i := range pkg.Imports {
imports = append(imports, i)
}
sort.Strings(imports)
r.SetPrivateAttr(config.GazelleImportsKey, imports)
for k, v := range pkg.Options {
r.SetPrivateAttr(k, v)
}
if shouldSetVisibility {
vis := checkInternalVisibility(rel, "//visibility:public")
r.SetAttr("visibility", []string{vis})
}
return r
}
// generateEmpty generates a list of proto_library rules that may be deleted.
// This is generated from existing proto_library rules with srcs lists that
// don't match any static or generated files.
func generateEmpty(f *rule.File, regularFiles, genFiles []string) []*rule.Rule {
if f == nil {
return nil
}
knownFiles := make(map[string]bool)
for _, f := range regularFiles {
knownFiles[f] = true
}
for _, f := range genFiles {
knownFiles[f] = true
}
var empty []*rule.Rule
outer:
for _, r := range f.Rules {
if r.Kind() != "proto_library" {
continue
}
srcs := r.AttrStrings("srcs")
if len(srcs) == 0 && r.Attr("srcs") != nil {
// srcs is not a string list; leave it alone
continue
}
for _, src := range r.AttrStrings("srcs") {
if knownFiles[src] {
continue outer
}
}
empty = append(empty, rule.NewRule("proto_library", r.Name()))
}
return empty
}
// hasDefaultVisibility returns whether oldFile contains a "package" rule with
// a "default_visibility" attribute. Rules generated by Gazelle should not
// have their own visibility attributes if this is the case.
func hasDefaultVisibility(f *rule.File) bool {
if f == nil {
return false
}
for _, r := range f.Rules {
if r.Kind() == "package" && r.Attr("default_visibility") != nil {
return true
}
}
return false
}
// checkInternalVisibility overrides the given visibility if the package is
// internal.
func checkInternalVisibility(rel, visibility string) string {
if i := strings.LastIndex(rel, "/internal/"); i >= 0 {
visibility = fmt.Sprintf("//%s:__subpackages__", rel[:i])
} else if strings.HasPrefix(rel, "internal/") {
visibility = "//:__subpackages__"
}
return visibility
}

View File

@@ -1,29 +0,0 @@
/* Copyright 2018 The Bazel Authors. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package proto
import "github.com/bazelbuild/bazel-gazelle/internal/rule"
var protoKinds = map[string]rule.KindInfo{
"proto_library": {
NonEmptyAttrs: map[string]bool{"srcs": true},
MergeableAttrs: map[string]bool{"srcs": true},
ResolveAttrs: map[string]bool{"deps": true},
},
}
func (_ *protoLang) Kinds() map[string]rule.KindInfo { return protoKinds }
func (_ *protoLang) Loads() []rule.LoadInfo { return nil }

View File

@@ -1,300 +0,0 @@
// Generated by internal/language/proto/gen/gen_known_imports.go
// From internal/language/proto/proto.csv
package proto
import "github.com/bazelbuild/bazel-gazelle/internal/label"
var knownImports = map[string]label.Label{
"google/protobuf/any.proto": label.New("com_google_protobuf", "", "any_proto"),
"google/protobuf/api.proto": label.New("com_google_protobuf", "", "api_proto"),
"google/protobuf/compiler/plugin.proto": label.New("com_google_protobuf", "", "compiler_plugin_proto"),
"google/protobuf/descriptor.proto": label.New("com_google_protobuf", "", "descriptor_proto"),
"google/protobuf/duration.proto": label.New("com_google_protobuf", "", "duration_proto"),
"google/protobuf/empty.proto": label.New("com_google_protobuf", "", "empty_proto"),
"google/protobuf/field_mask.proto": label.New("com_google_protobuf", "", "field_mask_proto"),
"google/protobuf/source_context.proto": label.New("com_google_protobuf", "", "source_context_proto"),
"google/protobuf/struct.proto": label.New("com_google_protobuf", "", "struct_proto"),
"google/protobuf/timestamp.proto": label.New("com_google_protobuf", "", "timestamp_proto"),
"google/protobuf/type.proto": label.New("com_google_protobuf", "", "type_proto"),
"google/protobuf/wrappers.proto": label.New("com_google_protobuf", "", "wrappers_proto"),
"google/assistant/embedded/v1alpha2/embedded_assistant.proto": label.New("go_googleapis", "google/assistant/embedded/v1alpha2", "embedded_proto"),
"google/assistant/embedded/v1alpha1/embedded_assistant.proto": label.New("go_googleapis", "google/assistant/embedded/v1alpha1", "embedded_proto"),
"google/home/graph/v1/device.proto": label.New("go_googleapis", "google/home/graph/v1", "graph_proto"),
"google/home/graph/v1/homegraph.proto": label.New("go_googleapis", "google/home/graph/v1", "graph_proto"),
"google/genomics/v1/operations.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_proto"),
"google/genomics/v1/variants.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_proto"),
"google/genomics/v1/position.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_proto"),
"google/genomics/v1/references.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_proto"),
"google/genomics/v1/cigar.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_proto"),
"google/genomics/v1/datasets.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_proto"),
"google/genomics/v1/readalignment.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_proto"),
"google/genomics/v1/annotations.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_proto"),
"google/genomics/v1/reads.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_proto"),
"google/genomics/v1/readgroup.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_proto"),
"google/genomics/v1/readgroupset.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_proto"),
"google/genomics/v1/range.proto": label.New("go_googleapis", "google/genomics/v1", "genomics_proto"),
"google/genomics/v1alpha2/pipelines.proto": label.New("go_googleapis", "google/genomics/v1alpha2", "genomics_proto"),
"google/bigtable/v1/bigtable_service_messages.proto": label.New("go_googleapis", "google/bigtable/v1", "bigtable_proto"),
"google/bigtable/v1/bigtable_service.proto": label.New("go_googleapis", "google/bigtable/v1", "bigtable_proto"),
"google/bigtable/v1/bigtable_data.proto": label.New("go_googleapis", "google/bigtable/v1", "bigtable_proto"),
"google/bigtable/admin/cluster/v1/bigtable_cluster_data.proto": label.New("go_googleapis", "google/bigtable/admin/cluster/v1", "cluster_proto"),
"google/bigtable/admin/cluster/v1/bigtable_cluster_service_messages.proto": label.New("go_googleapis", "google/bigtable/admin/cluster/v1", "cluster_proto"),
"google/bigtable/admin/cluster/v1/bigtable_cluster_service.proto": label.New("go_googleapis", "google/bigtable/admin/cluster/v1", "cluster_proto"),
"google/bigtable/admin/v2/bigtable_instance_admin.proto": label.New("go_googleapis", "google/bigtable/admin/v2", "admin_proto"),
"google/bigtable/admin/v2/instance.proto": label.New("go_googleapis", "google/bigtable/admin/v2", "admin_proto"),
"google/bigtable/admin/v2/table.proto": label.New("go_googleapis", "google/bigtable/admin/v2", "admin_proto"),
"google/bigtable/admin/v2/bigtable_table_admin.proto": label.New("go_googleapis", "google/bigtable/admin/v2", "admin_proto"),
"google/bigtable/admin/v2/common.proto": label.New("go_googleapis", "google/bigtable/admin/v2", "admin_proto"),
"google/bigtable/admin/table/v1/bigtable_table_service_messages.proto": label.New("go_googleapis", "google/bigtable/admin/table/v1", "table_proto"),
"google/bigtable/admin/table/v1/bigtable_table_service.proto": label.New("go_googleapis", "google/bigtable/admin/table/v1", "table_proto"),
"google/bigtable/admin/table/v1/bigtable_table_data.proto": label.New("go_googleapis", "google/bigtable/admin/table/v1", "table_proto"),
"google/bigtable/v2/bigtable.proto": label.New("go_googleapis", "google/bigtable/v2", "bigtable_proto"),
"google/bigtable/v2/data.proto": label.New("go_googleapis", "google/bigtable/v2", "bigtable_proto"),
"google/privacy/dlp/v2/storage.proto": label.New("go_googleapis", "google/privacy/dlp/v2", "dlp_proto"),
"google/privacy/dlp/v2/dlp.proto": label.New("go_googleapis", "google/privacy/dlp/v2", "dlp_proto"),
"google/watcher/v1/watch.proto": label.New("go_googleapis", "google/watcher/v1", "watcher_proto"),
"google/firestore/admin/v1beta1/firestore_admin.proto": label.New("go_googleapis", "google/firestore/admin/v1beta1", "admin_proto"),
"google/firestore/admin/v1beta1/index.proto": label.New("go_googleapis", "google/firestore/admin/v1beta1", "admin_proto"),
"google/firestore/v1beta1/write.proto": label.New("go_googleapis", "google/firestore/v1beta1", "firestore_proto"),
"google/firestore/v1beta1/document.proto": label.New("go_googleapis", "google/firestore/v1beta1", "firestore_proto"),
"google/firestore/v1beta1/firestore.proto": label.New("go_googleapis", "google/firestore/v1beta1", "firestore_proto"),
"google/firestore/v1beta1/query.proto": label.New("go_googleapis", "google/firestore/v1beta1", "firestore_proto"),
"google/firestore/v1beta1/common.proto": label.New("go_googleapis", "google/firestore/v1beta1", "firestore_proto"),
"google/example/library/v1/library.proto": label.New("go_googleapis", "google/example/library/v1", "library_proto"),
"google/appengine/v1/instance.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_proto"),
"google/appengine/v1/audit_data.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_proto"),
"google/appengine/v1/appengine.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_proto"),
"google/appengine/v1/application.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_proto"),
"google/appengine/v1/operation.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_proto"),
"google/appengine/v1/app_yaml.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_proto"),
"google/appengine/v1/location.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_proto"),
"google/appengine/v1/service.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_proto"),
"google/appengine/v1/deploy.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_proto"),
"google/appengine/v1/version.proto": label.New("go_googleapis", "google/appengine/v1", "appengine_proto"),
"google/appengine/legacy/audit_data.proto": label.New("go_googleapis", "google/appengine/legacy", "legacy_proto"),
"google/appengine/logging/v1/request_log.proto": label.New("go_googleapis", "google/appengine/logging/v1", "logging_proto"),
"google/storagetransfer/v1/transfer.proto": label.New("go_googleapis", "google/storagetransfer/v1", "storagetransfer_proto"),
"google/storagetransfer/v1/transfer_types.proto": label.New("go_googleapis", "google/storagetransfer/v1", "storagetransfer_proto"),
"google/longrunning/operations.proto": label.New("go_googleapis", "google/longrunning", "longrunning_proto"),
"google/container/v1/cluster_service.proto": label.New("go_googleapis", "google/container/v1", "container_proto"),
"google/container/v1beta1/cluster_service.proto": label.New("go_googleapis", "google/container/v1beta1", "container_proto"),
"google/container/v1alpha1/cluster_service.proto": label.New("go_googleapis", "google/container/v1alpha1", "container_proto"),
"google/datastore/v1beta3/datastore.proto": label.New("go_googleapis", "google/datastore/v1beta3", "datastore_proto"),
"google/datastore/v1beta3/query.proto": label.New("go_googleapis", "google/datastore/v1beta3", "datastore_proto"),
"google/datastore/v1beta3/entity.proto": label.New("go_googleapis", "google/datastore/v1beta3", "datastore_proto"),
"google/datastore/v1/datastore.proto": label.New("go_googleapis", "google/datastore/v1", "datastore_proto"),
"google/datastore/v1/query.proto": label.New("go_googleapis", "google/datastore/v1", "datastore_proto"),
"google/datastore/v1/entity.proto": label.New("go_googleapis", "google/datastore/v1", "datastore_proto"),
"google/datastore/admin/v1/datastore_admin.proto": label.New("go_googleapis", "google/datastore/admin/v1", "admin_proto"),
"google/datastore/admin/v1beta1/datastore_admin.proto": label.New("go_googleapis", "google/datastore/admin/v1beta1", "admin_proto"),
"google/bytestream/bytestream.proto": label.New("go_googleapis", "google/bytestream", "bytestream_proto"),
"google/iam/v1/iam_policy.proto": label.New("go_googleapis", "google/iam/v1", "iam_proto"),
"google/iam/v1/policy.proto": label.New("go_googleapis", "google/iam/v1", "iam_proto"),
"google/iam/v1/logging/audit_data.proto": label.New("go_googleapis", "google/iam/v1/logging", "logging_proto"),
"google/iam/admin/v1/iam.proto": label.New("go_googleapis", "google/iam/admin/v1", "admin_proto"),
"google/type/money.proto": label.New("go_googleapis", "google/type", "money_proto"),
"google/type/latlng.proto": label.New("go_googleapis", "google/type", "latlng_proto"),
"google/type/color.proto": label.New("go_googleapis", "google/type", "color_proto"),
"google/type/timeofday.proto": label.New("go_googleapis", "google/type", "timeofday_proto"),
"google/type/date.proto": label.New("go_googleapis", "google/type", "date_proto"),
"google/type/dayofweek.proto": label.New("go_googleapis", "google/type", "dayofweek_proto"),
"google/type/postal_address.proto": label.New("go_googleapis", "google/type", "postaladdress_proto"),
"google/devtools/clouderrorreporting/v1beta1/report_errors_service.proto": label.New("go_googleapis", "google/devtools/clouderrorreporting/v1beta1", "clouderrorreporting_proto"),
"google/devtools/clouderrorreporting/v1beta1/error_group_service.proto": label.New("go_googleapis", "google/devtools/clouderrorreporting/v1beta1", "clouderrorreporting_proto"),
"google/devtools/clouderrorreporting/v1beta1/error_stats_service.proto": label.New("go_googleapis", "google/devtools/clouderrorreporting/v1beta1", "clouderrorreporting_proto"),
"google/devtools/clouderrorreporting/v1beta1/common.proto": label.New("go_googleapis", "google/devtools/clouderrorreporting/v1beta1", "clouderrorreporting_proto"),
"google/devtools/resultstore/v2/file.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_proto"),
"google/devtools/resultstore/v2/resultstore_download.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_proto"),
"google/devtools/resultstore/v2/configuration.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_proto"),
"google/devtools/resultstore/v2/action.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_proto"),
"google/devtools/resultstore/v2/resultstore_file_download.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_proto"),
"google/devtools/resultstore/v2/test_suite.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_proto"),
"google/devtools/resultstore/v2/file_set.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_proto"),
"google/devtools/resultstore/v2/coverage.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_proto"),
"google/devtools/resultstore/v2/coverage_summary.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_proto"),
"google/devtools/resultstore/v2/configured_target.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_proto"),
"google/devtools/resultstore/v2/target.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_proto"),
"google/devtools/resultstore/v2/invocation.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_proto"),
"google/devtools/resultstore/v2/common.proto": label.New("go_googleapis", "google/devtools/resultstore/v2", "resultstore_proto"),
"google/devtools/source/v1/source_context.proto": label.New("go_googleapis", "google/devtools/source/v1", "source_proto"),
"google/devtools/remoteexecution/v1test/remote_execution.proto": label.New("go_googleapis", "google/devtools/remoteexecution/v1test", "remoteexecution_proto"),
"google/devtools/cloudbuild/v1/cloudbuild.proto": label.New("go_googleapis", "google/devtools/cloudbuild/v1", "cloudbuild_proto"),
"google/devtools/sourcerepo/v1/sourcerepo.proto": label.New("go_googleapis", "google/devtools/sourcerepo/v1", "sourcerepo_proto"),
"google/devtools/remoteworkers/v1test2/worker.proto": label.New("go_googleapis", "google/devtools/remoteworkers/v1test2", "remoteworkers_proto"),
"google/devtools/remoteworkers/v1test2/tasks.proto": label.New("go_googleapis", "google/devtools/remoteworkers/v1test2", "remoteworkers_proto"),
"google/devtools/remoteworkers/v1test2/bots.proto": label.New("go_googleapis", "google/devtools/remoteworkers/v1test2", "remoteworkers_proto"),
"google/devtools/remoteworkers/v1test2/command.proto": label.New("go_googleapis", "google/devtools/remoteworkers/v1test2", "remoteworkers_proto"),
"google/devtools/cloudtrace/v1/trace.proto": label.New("go_googleapis", "google/devtools/cloudtrace/v1", "cloudtrace_proto"),
"google/devtools/cloudtrace/v2/trace.proto": label.New("go_googleapis", "google/devtools/cloudtrace/v2", "cloudtrace_proto"),
"google/devtools/cloudtrace/v2/tracing.proto": label.New("go_googleapis", "google/devtools/cloudtrace/v2", "cloudtrace_proto"),
"google/devtools/cloudprofiler/v2/profiler.proto": label.New("go_googleapis", "google/devtools/cloudprofiler/v2", "cloudprofiler_proto"),
"google/devtools/containeranalysis/v1alpha1/containeranalysis.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1alpha1", "containeranalysis_proto"),
"google/devtools/containeranalysis/v1alpha1/bill_of_materials.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1alpha1", "containeranalysis_proto"),
"google/devtools/containeranalysis/v1alpha1/provenance.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1alpha1", "containeranalysis_proto"),
"google/devtools/containeranalysis/v1alpha1/package_vulnerability.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1alpha1", "containeranalysis_proto"),
"google/devtools/containeranalysis/v1alpha1/source_context.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1alpha1", "containeranalysis_proto"),
"google/devtools/containeranalysis/v1alpha1/image_basis.proto": label.New("go_googleapis", "google/devtools/containeranalysis/v1alpha1", "containeranalysis_proto"),
"google/devtools/build/v1/build_events.proto": label.New("go_googleapis", "google/devtools/build/v1", "build_proto"),
"google/devtools/build/v1/build_status.proto": label.New("go_googleapis", "google/devtools/build/v1", "build_proto"),
"google/devtools/build/v1/publish_build_event.proto": label.New("go_googleapis", "google/devtools/build/v1", "build_proto"),
"google/devtools/clouddebugger/v2/debugger.proto": label.New("go_googleapis", "google/devtools/clouddebugger/v2", "clouddebugger_proto"),
"google/devtools/clouddebugger/v2/data.proto": label.New("go_googleapis", "google/devtools/clouddebugger/v2", "clouddebugger_proto"),
"google/devtools/clouddebugger/v2/controller.proto": label.New("go_googleapis", "google/devtools/clouddebugger/v2", "clouddebugger_proto"),
"google/cloud/resourcemanager/v2/folders.proto": label.New("go_googleapis", "google/cloud/resourcemanager/v2", "resourcemanager_proto"),
"google/cloud/kms/v1/resources.proto": label.New("go_googleapis", "google/cloud/kms/v1", "kms_proto"),
"google/cloud/kms/v1/service.proto": label.New("go_googleapis", "google/cloud/kms/v1", "kms_proto"),
"google/cloud/runtimeconfig/v1beta1/resources.proto": label.New("go_googleapis", "google/cloud/runtimeconfig/v1beta1", "runtimeconfig_proto"),
"google/cloud/runtimeconfig/v1beta1/runtimeconfig.proto": label.New("go_googleapis", "google/cloud/runtimeconfig/v1beta1", "runtimeconfig_proto"),
"google/cloud/tasks/v2beta2/queue.proto": label.New("go_googleapis", "google/cloud/tasks/v2beta2", "tasks_proto"),
"google/cloud/tasks/v2beta2/task.proto": label.New("go_googleapis", "google/cloud/tasks/v2beta2", "tasks_proto"),
"google/cloud/tasks/v2beta2/target.proto": label.New("go_googleapis", "google/cloud/tasks/v2beta2", "tasks_proto"),
"google/cloud/tasks/v2beta2/cloudtasks.proto": label.New("go_googleapis", "google/cloud/tasks/v2beta2", "tasks_proto"),
"google/cloud/oslogin/v1/oslogin.proto": label.New("go_googleapis", "google/cloud/oslogin/v1", "oslogin_proto"),
"google/cloud/oslogin/v1alpha/oslogin.proto": label.New("go_googleapis", "google/cloud/oslogin/v1alpha", "oslogin_proto"),
"google/cloud/oslogin/common/common.proto": label.New("go_googleapis", "google/cloud/oslogin/common", "common_proto"),
"google/cloud/oslogin/v1beta/oslogin.proto": label.New("go_googleapis", "google/cloud/oslogin/v1beta", "oslogin_proto"),
"google/cloud/dialogflow/v2beta1/context.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_proto"),
"google/cloud/dialogflow/v2beta1/session_entity_type.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_proto"),
"google/cloud/dialogflow/v2beta1/intent.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_proto"),
"google/cloud/dialogflow/v2beta1/entity_type.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_proto"),
"google/cloud/dialogflow/v2beta1/webhook.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_proto"),
"google/cloud/dialogflow/v2beta1/session.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_proto"),
"google/cloud/dialogflow/v2beta1/agent.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2beta1", "dialogflow_proto"),
"google/cloud/dialogflow/v2/context.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_proto"),
"google/cloud/dialogflow/v2/session_entity_type.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_proto"),
"google/cloud/dialogflow/v2/intent.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_proto"),
"google/cloud/dialogflow/v2/entity_type.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_proto"),
"google/cloud/dialogflow/v2/webhook.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_proto"),
"google/cloud/dialogflow/v2/session.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_proto"),
"google/cloud/dialogflow/v2/agent.proto": label.New("go_googleapis", "google/cloud/dialogflow/v2", "dialogflow_proto"),
"google/cloud/redis/v1beta1/cloud_redis.proto": label.New("go_googleapis", "google/cloud/redis/v1beta1", "redis_proto"),
"google/cloud/location/locations.proto": label.New("go_googleapis", "google/cloud/location", "location_proto"),
"google/cloud/websecurityscanner/v1alpha/finding.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_proto"),
"google/cloud/websecurityscanner/v1alpha/finding_type_stats.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_proto"),
"google/cloud/websecurityscanner/v1alpha/scan_config.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_proto"),
"google/cloud/websecurityscanner/v1alpha/crawled_url.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_proto"),
"google/cloud/websecurityscanner/v1alpha/scan_run.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_proto"),
"google/cloud/websecurityscanner/v1alpha/web_security_scanner.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_proto"),
"google/cloud/websecurityscanner/v1alpha/finding_addon.proto": label.New("go_googleapis", "google/cloud/websecurityscanner/v1alpha", "websecurityscanner_proto"),
"google/cloud/language/v1/language_service.proto": label.New("go_googleapis", "google/cloud/language/v1", "language_proto"),
"google/cloud/language/v1beta2/language_service.proto": label.New("go_googleapis", "google/cloud/language/v1beta2", "language_proto"),
"google/cloud/language/v1beta1/language_service.proto": label.New("go_googleapis", "google/cloud/language/v1beta1", "language_proto"),
"google/cloud/bigquery/datatransfer/v1/transfer.proto": label.New("go_googleapis", "google/cloud/bigquery/datatransfer/v1", "datatransfer_proto"),
"google/cloud/bigquery/datatransfer/v1/datatransfer.proto": label.New("go_googleapis", "google/cloud/bigquery/datatransfer/v1", "datatransfer_proto"),
"google/cloud/bigquery/logging/v1/audit_data.proto": label.New("go_googleapis", "google/cloud/bigquery/logging/v1", "logging_proto"),
"google/cloud/vision/v1/image_annotator.proto": label.New("go_googleapis", "google/cloud/vision/v1", "vision_proto"),
"google/cloud/vision/v1/geometry.proto": label.New("go_googleapis", "google/cloud/vision/v1", "vision_proto"),
"google/cloud/vision/v1/web_detection.proto": label.New("go_googleapis", "google/cloud/vision/v1", "vision_proto"),
"google/cloud/vision/v1/text_annotation.proto": label.New("go_googleapis", "google/cloud/vision/v1", "vision_proto"),
"google/cloud/vision/v1p2beta1/image_annotator.proto": label.New("go_googleapis", "google/cloud/vision/v1p2beta1", "vision_proto"),
"google/cloud/vision/v1p2beta1/geometry.proto": label.New("go_googleapis", "google/cloud/vision/v1p2beta1", "vision_proto"),
"google/cloud/vision/v1p2beta1/web_detection.proto": label.New("go_googleapis", "google/cloud/vision/v1p2beta1", "vision_proto"),
"google/cloud/vision/v1p2beta1/text_annotation.proto": label.New("go_googleapis", "google/cloud/vision/v1p2beta1", "vision_proto"),
"google/cloud/vision/v1p1beta1/image_annotator.proto": label.New("go_googleapis", "google/cloud/vision/v1p1beta1", "vision_proto"),
"google/cloud/vision/v1p1beta1/geometry.proto": label.New("go_googleapis", "google/cloud/vision/v1p1beta1", "vision_proto"),
"google/cloud/vision/v1p1beta1/web_detection.proto": label.New("go_googleapis", "google/cloud/vision/v1p1beta1", "vision_proto"),
"google/cloud/vision/v1p1beta1/text_annotation.proto": label.New("go_googleapis", "google/cloud/vision/v1p1beta1", "vision_proto"),
"google/cloud/speech/v1/cloud_speech.proto": label.New("go_googleapis", "google/cloud/speech/v1", "speech_proto"),
"google/cloud/speech/v1beta1/cloud_speech.proto": label.New("go_googleapis", "google/cloud/speech/v1beta1", "speech_proto"),
"google/cloud/speech/v1p1beta1/cloud_speech.proto": label.New("go_googleapis", "google/cloud/speech/v1p1beta1", "speech_proto"),
"google/cloud/iot/v1/device_manager.proto": label.New("go_googleapis", "google/cloud/iot/v1", "iot_proto"),
"google/cloud/iot/v1/resources.proto": label.New("go_googleapis", "google/cloud/iot/v1", "iot_proto"),
"google/cloud/videointelligence/v1/video_intelligence.proto": label.New("go_googleapis", "google/cloud/videointelligence/v1", "videointelligence_proto"),
"google/cloud/videointelligence/v1beta2/video_intelligence.proto": label.New("go_googleapis", "google/cloud/videointelligence/v1beta2", "videointelligence_proto"),
"google/cloud/videointelligence/v1beta1/video_intelligence.proto": label.New("go_googleapis", "google/cloud/videointelligence/v1beta1", "videointelligence_proto"),
"google/cloud/videointelligence/v1p1beta1/video_intelligence.proto": label.New("go_googleapis", "google/cloud/videointelligence/v1p1beta1", "videointelligence_proto"),
"google/cloud/audit/audit_log.proto": label.New("go_googleapis", "google/cloud/audit", "audit_proto"),
"google/cloud/support/common.proto": label.New("go_googleapis", "google/cloud/support", "common_proto"),
"google/cloud/support/v1alpha1/cloud_support.proto": label.New("go_googleapis", "google/cloud/support/v1alpha1", "support_proto"),
"google/cloud/ml/v1/operation_metadata.proto": label.New("go_googleapis", "google/cloud/ml/v1", "ml_proto"),
"google/cloud/ml/v1/job_service.proto": label.New("go_googleapis", "google/cloud/ml/v1", "ml_proto"),
"google/cloud/ml/v1/prediction_service.proto": label.New("go_googleapis", "google/cloud/ml/v1", "ml_proto"),
"google/cloud/ml/v1/model_service.proto": label.New("go_googleapis", "google/cloud/ml/v1", "ml_proto"),
"google/cloud/ml/v1/project_service.proto": label.New("go_googleapis", "google/cloud/ml/v1", "ml_proto"),
"google/cloud/texttospeech/v1/cloud_tts.proto": label.New("go_googleapis", "google/cloud/texttospeech/v1", "texttospeech_proto"),
"google/cloud/texttospeech/v1beta1/cloud_tts.proto": label.New("go_googleapis", "google/cloud/texttospeech/v1beta1", "texttospeech_proto"),
"google/cloud/functions/v1beta2/operations.proto": label.New("go_googleapis", "google/cloud/functions/v1beta2", "functions_proto"),
"google/cloud/functions/v1beta2/functions.proto": label.New("go_googleapis", "google/cloud/functions/v1beta2", "functions_proto"),
"google/cloud/billing/v1/cloud_billing.proto": label.New("go_googleapis", "google/cloud/billing/v1", "billing_proto"),
"google/cloud/dataproc/v1/operations.proto": label.New("go_googleapis", "google/cloud/dataproc/v1", "dataproc_proto"),
"google/cloud/dataproc/v1/clusters.proto": label.New("go_googleapis", "google/cloud/dataproc/v1", "dataproc_proto"),
"google/cloud/dataproc/v1/jobs.proto": label.New("go_googleapis", "google/cloud/dataproc/v1", "dataproc_proto"),
"google/cloud/dataproc/v1beta2/operations.proto": label.New("go_googleapis", "google/cloud/dataproc/v1beta2", "dataproc_proto"),
"google/cloud/dataproc/v1beta2/clusters.proto": label.New("go_googleapis", "google/cloud/dataproc/v1beta2", "dataproc_proto"),
"google/cloud/dataproc/v1beta2/jobs.proto": label.New("go_googleapis", "google/cloud/dataproc/v1beta2", "dataproc_proto"),
"google/cloud/dataproc/v1beta2/workflow_templates.proto": label.New("go_googleapis", "google/cloud/dataproc/v1beta2", "dataproc_proto"),
"google/cloud/dataproc/v1beta2/shared.proto": label.New("go_googleapis", "google/cloud/dataproc/v1beta2", "dataproc_proto"),
"google/api/context.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"),
"google/api/http.proto": label.New("go_googleapis", "google/api", "annotations_proto"),
"google/api/config_change.proto": label.New("go_googleapis", "google/api", "configchange_proto"),
"google/api/system_parameter.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"),
"google/api/monitoring.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"),
"google/api/distribution.proto": label.New("go_googleapis", "google/api", "distribution_proto"),
"google/api/endpoint.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"),
"google/api/usage.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"),
"google/api/monitored_resource.proto": label.New("go_googleapis", "google/api", "monitoredres_proto"),
"google/api/annotations.proto": label.New("go_googleapis", "google/api", "annotations_proto"),
"google/api/control.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"),
"google/api/metric.proto": label.New("go_googleapis", "google/api", "metric_proto"),
"google/api/label.proto": label.New("go_googleapis", "google/api", "label_proto"),
"google/api/consumer.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"),
"google/api/log.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"),
"google/api/billing.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"),
"google/api/service.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"),
"google/api/logging.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"),
"google/api/documentation.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"),
"google/api/quota.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"),
"google/api/auth.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"),
"google/api/backend.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"),
"google/api/source_info.proto": label.New("go_googleapis", "google/api", "serviceconfig_proto"),
"google/api/httpbody.proto": label.New("go_googleapis", "google/api", "httpbody_proto"),
"google/api/experimental/authorization_config.proto": label.New("go_googleapis", "google/api/experimental", "api_proto"),
"google/api/experimental/experimental.proto": label.New("go_googleapis", "google/api/experimental", "api_proto"),
"google/api/servicemanagement/v1/servicemanager.proto": label.New("go_googleapis", "google/api/servicemanagement/v1", "servicemanagement_proto"),
"google/api/servicemanagement/v1/resources.proto": label.New("go_googleapis", "google/api/servicemanagement/v1", "servicemanagement_proto"),
"google/api/servicecontrol/v1/quota_controller.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_proto"),
"google/api/servicecontrol/v1/distribution.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_proto"),
"google/api/servicecontrol/v1/check_error.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_proto"),
"google/api/servicecontrol/v1/operation.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_proto"),
"google/api/servicecontrol/v1/metric_value.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_proto"),
"google/api/servicecontrol/v1/log_entry.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_proto"),
"google/api/servicecontrol/v1/service_controller.proto": label.New("go_googleapis", "google/api/servicecontrol/v1", "servicecontrol_proto"),
"google/pubsub/v1/pubsub.proto": label.New("go_googleapis", "google/pubsub/v1", "pubsub_proto"),
"google/pubsub/v1beta2/pubsub.proto": label.New("go_googleapis", "google/pubsub/v1beta2", "pubsub_proto"),
"google/spanner/v1/mutation.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_proto"),
"google/spanner/v1/spanner.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_proto"),
"google/spanner/v1/transaction.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_proto"),
"google/spanner/v1/keys.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_proto"),
"google/spanner/v1/type.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_proto"),
"google/spanner/v1/query_plan.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_proto"),
"google/spanner/v1/result_set.proto": label.New("go_googleapis", "google/spanner/v1", "spanner_proto"),
"google/spanner/admin/database/v1/spanner_database_admin.proto": label.New("go_googleapis", "google/spanner/admin/database/v1", "database_proto"),
"google/spanner/admin/instance/v1/spanner_instance_admin.proto": label.New("go_googleapis", "google/spanner/admin/instance/v1", "instance_proto"),
"google/monitoring/v3/group.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_proto"),
"google/monitoring/v3/mutation_record.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_proto"),
"google/monitoring/v3/notification.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_proto"),
"google/monitoring/v3/alert_service.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_proto"),
"google/monitoring/v3/uptime_service.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_proto"),
"google/monitoring/v3/group_service.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_proto"),
"google/monitoring/v3/alert.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_proto"),
"google/monitoring/v3/uptime.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_proto"),
"google/monitoring/v3/metric.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_proto"),
"google/monitoring/v3/notification_service.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_proto"),
"google/monitoring/v3/metric_service.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_proto"),
"google/monitoring/v3/common.proto": label.New("go_googleapis", "google/monitoring/v3", "monitoring_proto"),
"google/rpc/code.proto": label.New("go_googleapis", "google/rpc", "code_proto"),
"google/rpc/status.proto": label.New("go_googleapis", "google/rpc", "status_proto"),
"google/rpc/error_details.proto": label.New("go_googleapis", "google/rpc", "errdetails_proto"),
"google/streetview/publish/v1/resources.proto": label.New("go_googleapis", "google/streetview/publish/v1", "publish_proto"),
"google/streetview/publish/v1/rpcmessages.proto": label.New("go_googleapis", "google/streetview/publish/v1", "publish_proto"),
"google/streetview/publish/v1/streetview_publish.proto": label.New("go_googleapis", "google/streetview/publish/v1", "publish_proto"),
"google/logging/v2/logging_metrics.proto": label.New("go_googleapis", "google/logging/v2", "logging_proto"),
"google/logging/v2/logging_config.proto": label.New("go_googleapis", "google/logging/v2", "logging_proto"),
"google/logging/v2/log_entry.proto": label.New("go_googleapis", "google/logging/v2", "logging_proto"),
"google/logging/v2/logging.proto": label.New("go_googleapis", "google/logging/v2", "logging_proto"),
"google/logging/type/log_severity.proto": label.New("go_googleapis", "google/logging/type", "ltype_proto"),
"google/logging/type/http_request.proto": label.New("go_googleapis", "google/logging/type", "ltype_proto"),
}

View File

@@ -1,72 +0,0 @@
/* Copyright 2018 The Bazel Authors. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package proto provides support for protocol buffer rules.
// It generates proto_library rules only (not go_proto_library or any other
// language-specific implementations).
//
// Configuration
//
// Configuration is largely controlled by Mode. In disable mode, proto rules are
// left alone (neither generated nor deleted). In legacy mode, filegroups are
// emitted containing protos. In default mode, proto_library rules are
// emitted. The proto mode may be set with the -proto command line flag or the
// "# gazelle:proto" directive.
//
// The configuration is largely public, and other languages may depend on it.
// For example, go uses Mode to determine whether to generate go_proto_library
// rules and ignore static .pb.go files.
//
// Rule generation
//
// Currently, Gazelle generates at most one proto_library per directory. Protos
// in the same package are grouped together into a proto_library. If there are
// sources for multiple packages, the package name that matches the directory
// name will be chosen; if there is no such package, an error will be printed.
// We expect to provide support for multiple proto_libraries in the future
// when Go has support for multiple packages and we have better rule matching.
// The generated proto_library will be named after the directory, not the
// proto or the package. For example, for foo/bar/baz.proto, a proto_library
// rule will be generated named //foo/bar:bar_proto.
//
// Dependency resolution
//
// proto_library rules are indexed by their srcs attribute. Gazelle attempts
// to resolve proto imports (e.g., import foo/bar/bar.proto) to the
// proto_library that contains the named source file
// (e.g., //foo/bar:bar_proto). If no indexed proto_library provides the source
// file, Gazelle will guess a label, following conventions.
//
// No attempt is made to resolve protos to rules in external repositories,
// since there's no indication that a proto import comes from an external
// repository. In the future, build files in external repos will be indexed,
// so we can support this (#12).
//
// Gazelle has special cases for Well Known Types (i.e., imports of the form
// google/protobuf/*.proto). These are resolved to rules in
// @com_google_protobuf.
package proto
import "github.com/bazelbuild/bazel-gazelle/internal/language"
const protoName = "proto"
type protoLang struct{}
func (_ *protoLang) Name() string { return protoName }
func New() language.Language {
return &protoLang{}
}

View File

@@ -1,55 +0,0 @@
/* Copyright 2018 The Bazel Authors. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package proto
import "path/filepath"
// Package contains metadata for a set of .proto files that have the
// same package name. This translates to a proto_library rule.
type Package struct {
Name string
Files map[string]FileInfo
Imports map[string]bool
Options map[string]string
HasServices bool
}
func newPackage(name string) *Package {
return &Package{
Name: name,
Files: map[string]FileInfo{},
Imports: map[string]bool{},
Options: map[string]string{},
}
}
func (p *Package) addFile(info FileInfo) {
p.Files[info.Name] = info
for _, imp := range info.Imports {
p.Imports[imp] = true
}
for _, opt := range info.Options {
p.Options[opt.Key] = opt.Value
}
p.HasServices = p.HasServices || info.HasServices
}
func (p *Package) addGenFile(dir, name string) {
p.Files[name] = FileInfo{
Name: name,
Path: filepath.Join(dir, filepath.FromSlash(name)),
}
}

View File

@@ -1,116 +0,0 @@
/* Copyright 2018 The Bazel Authors. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package proto
import (
"errors"
"fmt"
"log"
"path"
"strings"
"github.com/bazelbuild/bazel-gazelle/internal/config"
"github.com/bazelbuild/bazel-gazelle/internal/label"
"github.com/bazelbuild/bazel-gazelle/internal/repos"
"github.com/bazelbuild/bazel-gazelle/internal/resolve"
"github.com/bazelbuild/bazel-gazelle/internal/rule"
)
func (_ *protoLang) Imports(c *config.Config, r *rule.Rule, f *rule.File) []resolve.ImportSpec {
rel := f.Pkg
srcs := r.AttrStrings("srcs")
imports := make([]resolve.ImportSpec, len(srcs))
for i, src := range srcs {
imports[i] = resolve.ImportSpec{Lang: "proto", Imp: path.Join(rel, src)}
}
return imports
}
func (_ *protoLang) Embeds(r *rule.Rule, from label.Label) []label.Label {
return nil
}
func (_ *protoLang) Resolve(c *config.Config, ix *resolve.RuleIndex, rc *repos.RemoteCache, r *rule.Rule, from label.Label) {
pc := GetProtoConfig(c)
importsRaw := r.PrivateAttr(config.GazelleImportsKey)
if importsRaw == nil {
// may not be set in tests.
return
}
imports := importsRaw.([]string)
r.DelAttr("deps")
deps := make([]string, 0, len(imports))
for _, imp := range imports {
l, err := resolveProto(pc, ix, r, imp, from)
if err == skipImportError {
continue
} else if err != nil {
log.Print(err)
} else {
l = l.Rel(from.Repo, from.Pkg)
deps = append(deps, l.String())
}
}
if len(deps) > 0 {
r.SetAttr("deps", deps)
}
}
var (
skipImportError = errors.New("std import")
notFoundError = errors.New("not found")
)
func resolveProto(pc *ProtoConfig, ix *resolve.RuleIndex, r *rule.Rule, imp string, from label.Label) (label.Label, error) {
if !strings.HasSuffix(imp, ".proto") {
return label.NoLabel, fmt.Errorf("can't import non-proto: %q", imp)
}
if l, ok := knownImports[imp]; ok && pc.Mode.ShouldUseKnownImports() {
if l.Equal(from) {
return label.NoLabel, skipImportError
} else {
return l, nil
}
}
if l, err := resolveWithIndex(ix, imp, from); err == nil || err == skipImportError {
return l, err
} else if err != notFoundError {
return label.NoLabel, err
}
rel := path.Dir(imp)
if rel == "." {
rel = ""
}
name := RuleName(rel)
return label.New("", rel, name), nil
}
func resolveWithIndex(ix *resolve.RuleIndex, imp string, from label.Label) (label.Label, error) {
matches := ix.FindRulesByImport(resolve.ImportSpec{Lang: "proto", Imp: imp}, "proto")
if len(matches) == 0 {
return label.NoLabel, notFoundError
}
if len(matches) > 1 {
return label.NoLabel, fmt.Errorf("multiple rules (%s and %s) may be imported with %q from %s", matches[0].Label, matches[1].Label, imp, from)
}
if matches[0].IsSelfImport(from) {
return label.NoLabel, skipImportError
}
return matches[0].Label, nil
}

View File

@@ -1,27 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"fix.go",
"merger.go",
],
importmap = "sigs.k8s.io/kind/vendor/github.com/bazelbuild/bazel-gazelle/internal/merger",
importpath = "github.com/bazelbuild/bazel-gazelle/internal/merger",
visibility = ["//vendor/github.com/bazelbuild/bazel-gazelle:__subpackages__"],
deps = ["//vendor/github.com/bazelbuild/bazel-gazelle/internal/rule:go_default_library"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -1,199 +0,0 @@
/* Copyright 2017 The Bazel Authors. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package merger
import (
"fmt"
"strings"
"github.com/bazelbuild/bazel-gazelle/internal/rule"
)
// FixLoads removes loads of unused go rules and adds loads of newly used rules.
// This should be called after FixFile and MergeFile, since symbols
// may be introduced that aren't loaded.
//
// This function calls File.Sync before processing loads.
func FixLoads(f *rule.File, knownLoads []rule.LoadInfo) {
knownFiles := make(map[string]bool)
knownKinds := make(map[string]string)
for _, l := range knownLoads {
knownFiles[l.Name] = true
for _, k := range l.Symbols {
knownKinds[k] = l.Name
}
}
// Sync the file. We need File.Loads and File.Rules to contain inserted
// statements and not deleted statements.
f.Sync()
// Scan load statements in the file. Keep track of loads of known files,
// since these may be changed. Keep track of symbols loaded from unknown
// files; we will not add loads for these.
var loads []*rule.Load
otherLoadedKinds := make(map[string]bool)
for _, l := range f.Loads {
if knownFiles[l.Name()] {
loads = append(loads, l)
continue
}
for _, sym := range l.Symbols() {
otherLoadedKinds[sym] = true
}
}
// Make a map of all the symbols from known files used in this file.
usedKinds := make(map[string]map[string]bool)
for _, r := range f.Rules {
kind := r.Kind()
if file, ok := knownKinds[kind]; ok && !otherLoadedKinds[kind] {
if usedKinds[file] == nil {
usedKinds[file] = make(map[string]bool)
}
usedKinds[file][kind] = true
}
}
// Fix the load statements. The order is important, so we iterate over
// knownLoads instead of knownFiles.
for _, known := range knownLoads {
file := known.Name
first := true
for _, l := range loads {
if l.Name() != file {
continue
}
if first {
fixLoad(l, file, usedKinds[file], knownKinds)
first = false
} else {
fixLoad(l, file, nil, knownKinds)
}
if l.IsEmpty() {
l.Delete()
}
}
if first {
load := fixLoad(nil, file, usedKinds[file], knownKinds)
if load != nil {
index := newLoadIndex(f, known.After)
load.Insert(f, index)
}
}
}
}
// fixLoad updates a load statement with the given symbols. If load is nil,
// a new load may be created and returned. Symbols in kinds will be added
// to the load if they're not already present. Known symbols not in kinds
// will be removed if present. Other symbols will be preserved. If load is
// empty, nil is returned.
func fixLoad(load *rule.Load, file string, kinds map[string]bool, knownKinds map[string]string) *rule.Load {
if load == nil {
if len(kinds) == 0 {
return nil
}
load = rule.NewLoad(file)
}
for k := range kinds {
load.Add(k)
}
for _, k := range load.Symbols() {
if knownKinds[k] != "" && !kinds[k] {
load.Remove(k)
}
}
return load
}
// newLoadIndex returns the index in stmts where a new load statement should
// be inserted. after is a list of function names that the load should not
// be inserted before.
func newLoadIndex(f *rule.File, after []string) int {
if len(after) == 0 {
return 0
}
index := 0
for _, r := range f.Rules {
for _, a := range after {
if r.Kind() == a && r.Index() >= index {
index = r.Index() + 1
}
}
}
return index
}
// FixWorkspace updates rules in the WORKSPACE file f that were used with an
// older version of rules_go or gazelle.
func FixWorkspace(f *rule.File) {
removeLegacyGoRepository(f)
}
// CheckGazelleLoaded searches the given WORKSPACE file for a repository named
// "bazel_gazelle". If no such repository is found *and* the repo is not
// declared with a directive *and* at least one load statement mentions
// the repository, a descriptive error will be returned.
//
// This should be called after modifications have been made to WORKSPACE
// (i.e., after FixLoads) before writing it to disk.
func CheckGazelleLoaded(f *rule.File) error {
needGazelle := false
for _, l := range f.Loads {
if strings.HasPrefix(l.Name(), "@bazel_gazelle//") {
needGazelle = true
}
}
if !needGazelle {
return nil
}
for _, r := range f.Rules {
if r.Name() == "bazel_gazelle" {
return nil
}
}
for _, d := range f.Directives {
if d.Key != "repo" {
continue
}
if fs := strings.Fields(d.Value); len(fs) > 0 && fs[0] == "bazel_gazelle" {
return nil
}
}
return fmt.Errorf(`%s: error: bazel_gazelle is not declared in WORKSPACE.
Without this repository, Gazelle cannot safely modify the WORKSPACE file.
See the instructions at https://github.com/bazelbuild/bazel-gazelle.
If the bazel_gazelle is declared inside a macro, you can suppress this error
by adding a comment like this to WORKSPACE:
# gazelle:repo bazel_gazelle
`, f.Path)
}
// removeLegacyGoRepository removes loads of go_repository from
// @io_bazel_rules_go. FixLoads should be called after this; it will load from
// @bazel_gazelle.
func removeLegacyGoRepository(f *rule.File) {
for _, l := range f.Loads {
if l.Name() == "@io_bazel_rules_go//go:def.bzl" {
l.Remove("go_repository")
if l.IsEmpty() {
l.Delete()
}
}
}
}

View File

@@ -1,199 +0,0 @@
/* Copyright 2016 The Bazel Authors. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package merger provides methods for merging parsed BUILD files.
package merger
import (
"fmt"
"strings"
"github.com/bazelbuild/bazel-gazelle/internal/rule"
)
// Phase indicates which attributes should be merged in matching rules.
//
// The pre-resolve merge is performed before rules are indexed for dependency
// resolution. All attributes not related to dependencies are merged. This
// merge must be performed indexing because attributes related to indexing
// (e.g., srcs, importpath) will be affected.
//
// The post-resolve merge is performed after rules are indexed. All attributes
// related to dependencies are merged.
type Phase int
const (
PreResolve Phase = iota
PostResolve
)
// MergeFile merges the rules in genRules with matching rules in f and
// adds unmatched rules to the end of the merged file. MergeFile also merges
// rules in empty with matching rules in f and deletes rules that
// are empty after merging. attrs is the set of attributes to merge. Attributes
// not in this set will be left alone if they already exist.
func MergeFile(oldFile *rule.File, emptyRules, genRules []*rule.Rule, phase Phase, kinds map[string]rule.KindInfo) {
getMergeAttrs := func(r *rule.Rule) map[string]bool {
if phase == PreResolve {
return kinds[r.Kind()].MergeableAttrs
} else {
return kinds[r.Kind()].ResolveAttrs
}
}
// Merge empty rules into the file and delete any rules which become empty.
for _, emptyRule := range emptyRules {
if oldRule, _ := match(oldFile.Rules, emptyRule, kinds[emptyRule.Kind()]); oldRule != nil {
if oldRule.ShouldKeep() {
continue
}
rule.MergeRules(emptyRule, oldRule, getMergeAttrs(emptyRule), oldFile.Path)
if oldRule.IsEmpty(kinds[oldRule.Kind()]) {
oldRule.Delete()
}
}
}
oldFile.Sync()
// Match generated rules with existing rules in the file. Keep track of
// rules with non-standard names.
matchRules := make([]*rule.Rule, len(genRules))
matchErrors := make([]error, len(genRules))
substitutions := make(map[string]string)
for i, genRule := range genRules {
oldRule, err := match(oldFile.Rules, genRule, kinds[genRule.Kind()])
if err != nil {
// TODO(jayconrod): add a verbose mode and log errors. They are too chatty
// to print by default.
matchErrors[i] = err
continue
}
matchRules[i] = oldRule
if oldRule != nil {
if oldRule.Name() != genRule.Name() {
substitutions[genRule.Name()] = oldRule.Name()
}
}
}
// Rename labels in generated rules that refer to other generated rules.
if len(substitutions) > 0 {
for _, genRule := range genRules {
substituteRule(genRule, substitutions, kinds[genRule.Kind()])
}
}
// Merge generated rules with existing rules or append to the end of the file.
for i, genRule := range genRules {
if matchErrors[i] != nil {
continue
}
if matchRules[i] == nil {
genRule.Insert(oldFile)
} else {
rule.MergeRules(genRule, matchRules[i], getMergeAttrs(genRule), oldFile.Path)
}
}
}
// substituteRule replaces local labels (those beginning with ":", referring to
// targets in the same package) according to a substitution map. This is used
// to update generated rules before merging when the corresponding existing
// rules have different names. If substituteRule replaces a string, it returns
// a new expression; it will not modify the original expression.
func substituteRule(r *rule.Rule, substitutions map[string]string, info rule.KindInfo) {
for attr := range info.SubstituteAttrs {
if expr := r.Attr(attr); expr != nil {
expr = rule.MapExprStrings(expr, func(s string) string {
if rename, ok := substitutions[strings.TrimPrefix(s, ":")]; ok {
return ":" + rename
} else {
return s
}
})
r.SetAttr(attr, expr)
}
}
}
// match searches for a rule that can be merged with x in rules.
//
// A rule is considered a match if its kind is equal to x's kind AND either its
// name is equal OR at least one of the attributes in matchAttrs is equal.
//
// If there are no matches, nil and nil are returned.
//
// If a rule has the same name but a different kind, nill and an error
// are returned.
//
// If there is exactly one match, the rule and nil are returned.
//
// If there are multiple matches, match will attempt to disambiguate, based on
// the quality of the match (name match is best, then attribute match in the
// order that attributes are listed). If disambiguation is successful,
// the rule and nil are returned. Otherwise, nil and an error are returned.
func match(rules []*rule.Rule, x *rule.Rule, info rule.KindInfo) (*rule.Rule, error) {
xname := x.Name()
xkind := x.Kind()
var nameMatches []*rule.Rule
var kindMatches []*rule.Rule
for _, y := range rules {
if xname == y.Name() {
nameMatches = append(nameMatches, y)
}
if xkind == y.Kind() {
kindMatches = append(kindMatches, y)
}
}
if len(nameMatches) == 1 {
y := nameMatches[0]
if xkind != y.Kind() {
return nil, fmt.Errorf("could not merge %s(%s): a rule of the same name has kind %s", xkind, xname, y.Kind())
}
return y, nil
}
if len(nameMatches) > 1 {
return nil, fmt.Errorf("could not merge %s(%s): multiple rules have the same name", xkind, xname)
}
for _, key := range info.MatchAttrs {
var attrMatches []*rule.Rule
xvalue := x.AttrString(key)
if xvalue == "" {
continue
}
for _, y := range kindMatches {
if xvalue == y.AttrString(key) {
attrMatches = append(attrMatches, y)
}
}
if len(attrMatches) == 1 {
return attrMatches[0], nil
} else if len(attrMatches) > 1 {
return nil, fmt.Errorf("could not merge %s(%s): multiple rules have the same attribute %s = %q", xkind, xname, key, xvalue)
}
}
if info.MatchAny {
if len(kindMatches) == 1 {
return kindMatches[0], nil
} else if len(kindMatches) > 1 {
return nil, fmt.Errorf("could not merge %s(%s): multiple rules have the same kind but different names", xkind, xname)
}
}
return nil, nil
}

View File

@@ -1,23 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["path.go"],
importmap = "sigs.k8s.io/kind/vendor/github.com/bazelbuild/bazel-gazelle/internal/pathtools",
importpath = "github.com/bazelbuild/bazel-gazelle/internal/pathtools",
visibility = ["//vendor/github.com/bazelbuild/bazel-gazelle:__subpackages__"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -1,63 +0,0 @@
/* Copyright 2018 The Bazel Authors. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package pathtools
import (
"path"
"path/filepath"
"strings"
)
// HasPrefix returns whether the slash-separated path p has the given
// prefix. Unlike strings.HasPrefix, this function respects component
// boundaries, so "/home/foo" is not a prefix is "/home/foobar/baz". If the
// prefix is empty, this function always returns true.
func HasPrefix(p, prefix string) bool {
return prefix == "" || p == prefix || strings.HasPrefix(p, prefix+"/")
}
// TrimPrefix returns p without the provided prefix. If p doesn't start
// with prefix, it returns p unchanged. Unlike strings.HasPrefix, this function
// respects component boundaries (assuming slash-separated paths), so
// TrimPrefix("foo/bar", "foo") returns "baz".
func TrimPrefix(p, prefix string) string {
if prefix == "" {
return p
}
if prefix == p {
return ""
}
return strings.TrimPrefix(p, prefix+"/")
}
// RelBaseName returns the base name for rel, a slash-separated path relative
// to the repository root. If rel is empty, RelBaseName returns the base name
// of prefix. If prefix is empty, RelBaseName returns the base name of root,
// the absolute file path of the repository root directory. If that's empty
// to, then RelBaseName returns "root".
func RelBaseName(rel, prefix, root string) string {
base := path.Base(rel)
if base == "." || base == "/" {
base = path.Base(prefix)
}
if base == "." || base == "/" {
base = filepath.Base(root)
}
if base == "." || base == "/" {
base = "root"
}
return base
}

View File

@@ -1,34 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"dep.go",
"remote.go",
"repo.go",
],
importmap = "sigs.k8s.io/kind/vendor/github.com/bazelbuild/bazel-gazelle/internal/repos",
importpath = "github.com/bazelbuild/bazel-gazelle/internal/repos",
visibility = ["//vendor/github.com/bazelbuild/bazel-gazelle:__subpackages__"],
deps = [
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/label:go_default_library",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/pathtools:go_default_library",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/rule:go_default_library",
"//vendor/github.com/pelletier/go-toml:go_default_library",
"//vendor/golang.org/x/tools/go/vcs:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -1,55 +0,0 @@
/* Copyright 2017 The Bazel Authors. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package repos
import (
"io/ioutil"
"github.com/bazelbuild/bazel-gazelle/internal/label"
toml "github.com/pelletier/go-toml"
)
type depLockFile struct {
Projects []depProject `toml:"projects"`
}
type depProject struct {
Name string `toml:"name"`
Revision string `toml:"revision"`
Source string `toml:"source"`
}
func importRepoRulesDep(filename string) ([]Repo, error) {
data, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}
var file depLockFile
if err := toml.Unmarshal(data, &file); err != nil {
return nil, err
}
var repos []Repo
for _, p := range file.Projects {
repos = append(repos, Repo{
Name: label.ImportPathToBazelRepoName(p.Name),
GoPrefix: p.Name,
Commit: p.Revision,
Remote: p.Source,
})
}
return repos, nil
}

View File

@@ -1,332 +0,0 @@
/* Copyright 2018 The Bazel Authors. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package repos
import (
"bytes"
"fmt"
"os/exec"
"path"
"regexp"
"strings"
"sync"
"github.com/bazelbuild/bazel-gazelle/internal/label"
"github.com/bazelbuild/bazel-gazelle/internal/pathtools"
"golang.org/x/tools/go/vcs"
)
// UpdateRepo returns an object describing a repository at the most recent
// commit or version tag.
//
// This function uses RemoteCache to retrieve information about the repository.
// Depending on how the RemoteCache was initialized and used earlier, some
// information may already be locally available. Frequently though, information
// will be fetched over the network, so this function may be slow.
func UpdateRepo(rc *RemoteCache, importPath string) (Repo, error) {
root, name, err := rc.Root(importPath)
if err != nil {
return Repo{}, err
}
remote, vcs, err := rc.Remote(root)
if err != nil {
return Repo{}, err
}
commit, tag, err := rc.Head(remote, vcs)
if err != nil {
return Repo{}, err
}
repo := Repo{
Name: name,
GoPrefix: root,
Commit: commit,
Tag: tag,
Remote: remote,
VCS: vcs,
}
return repo, nil
}
// RemoteCache stores information about external repositories. The cache may
// be initialized with information about known repositories, i.e., those listed
// in the WORKSPACE file and mentioned on the command line. Other information
// is retrieved over the network.
//
// Public methods of RemoteCache may be slow in cases where a network fetch
// is needed. Public methods may be called concurrently.
type RemoteCache struct {
// RepoRootForImportPath is vcs.RepoRootForImportPath by default. It may
// be overridden so that tests may avoid accessing the network.
RepoRootForImportPath func(string, bool) (*vcs.RepoRoot, error)
// HeadCmd returns the latest commit on the default branch in the given
// repository. This is used by Head. It may be stubbed out for tests.
HeadCmd func(remote, vcs string) (string, error)
root, remote, head remoteCacheMap
}
// remoteCacheMap is a thread-safe, idempotent cache. It is used to store
// information which should be fetched over the network no more than once.
// This follows the Memo pattern described in The Go Programming Language,
// section 9.7.
type remoteCacheMap struct {
mu sync.Mutex
cache map[string]*remoteCacheEntry
}
type remoteCacheEntry struct {
value interface{}
err error
// ready is nil for entries that were added when the cache was initialized.
// It is non-nil for other entries. It is closed when an entry is ready,
// i.e., the operation loading the entry completed.
ready chan struct{}
}
type rootValue struct {
root, name string
}
type remoteValue struct {
remote, vcs string
}
type headValue struct {
commit, tag string
}
// NewRemoteCache creates a new RemoteCache with a set of known repositories.
// The Root and Remote methods will return information about repositories listed
// here without accessing the network. However, the Head method will still
// access the network for these repositories to retrieve information about new
// versions.
func NewRemoteCache(knownRepos []Repo) *RemoteCache {
r := &RemoteCache{
RepoRootForImportPath: vcs.RepoRootForImportPath,
HeadCmd: defaultHeadCmd,
root: remoteCacheMap{cache: make(map[string]*remoteCacheEntry)},
remote: remoteCacheMap{cache: make(map[string]*remoteCacheEntry)},
head: remoteCacheMap{cache: make(map[string]*remoteCacheEntry)},
}
for _, repo := range knownRepos {
r.root.cache[repo.GoPrefix] = &remoteCacheEntry{
value: rootValue{
root: repo.GoPrefix,
name: repo.Name,
},
}
if repo.Remote != "" {
r.remote.cache[repo.GoPrefix] = &remoteCacheEntry{
value: remoteValue{
remote: repo.Remote,
vcs: repo.VCS,
},
}
}
}
return r
}
var gopkginPattern = regexp.MustCompile("^(gopkg.in/(?:[^/]+/)?[^/]+\\.v\\d+)(?:/|$)")
var knownPrefixes = []struct {
prefix string
missing int
}{
{prefix: "golang.org/x", missing: 1},
{prefix: "google.golang.org", missing: 1},
{prefix: "cloud.google.com", missing: 1},
{prefix: "github.com", missing: 2},
}
// Root returns the portion of an import path that corresponds to the root
// directory of the repository containing the given import path. For example,
// given "golang.org/x/tools/go/loader", this will return "golang.org/x/tools".
// The workspace name of the repository is also returned. This may be a custom
// name set in WORKSPACE, or it may be a generated name based on the root path.
func (r *RemoteCache) Root(importPath string) (root, name string, err error) {
// Try prefixes of the import path in the cache, but don't actually go out
// to vcs yet. We do this before handling known special cases because
// the cache is pre-populated with repository rules, and we want to use their
// names if we can.
prefix := importPath
for {
v, ok, err := r.root.get(prefix)
if ok {
if err != nil {
return "", "", err
}
value := v.(rootValue)
return value.root, value.name, nil
}
prefix = path.Dir(prefix)
if prefix == "." || prefix == "/" {
break
}
}
// Try known prefixes.
for _, p := range knownPrefixes {
if pathtools.HasPrefix(importPath, p.prefix) {
rest := pathtools.TrimPrefix(importPath, p.prefix)
var components []string
if rest != "" {
components = strings.Split(rest, "/")
}
if len(components) < p.missing {
return "", "", fmt.Errorf("import path %q is shorter than the known prefix %q", importPath, p.prefix)
}
root = p.prefix
for _, c := range components[:p.missing] {
root = path.Join(root, c)
}
name = label.ImportPathToBazelRepoName(root)
return root, name, nil
}
}
// gopkg.in is special, and might have either one or two levels of
// missing paths. See http://labix.org/gopkg.in for URL patterns.
if match := gopkginPattern.FindStringSubmatch(importPath); len(match) > 0 {
root = match[1]
name = label.ImportPathToBazelRepoName(root)
return root, name, nil
}
// Find the prefix using vcs and cache the result.
v, err := r.root.ensure(importPath, func() (interface{}, error) {
res, err := r.RepoRootForImportPath(importPath, false)
if err != nil {
return nil, err
}
return rootValue{res.Root, label.ImportPathToBazelRepoName(res.Root)}, nil
})
if err != nil {
return "", "", err
}
value := v.(rootValue)
return value.root, value.name, nil
}
// Remote returns the VCS name and the remote URL for a repository with the
// given root import path. This is suitable for creating new repository rules.
func (r *RemoteCache) Remote(root string) (remote, vcs string, err error) {
v, err := r.remote.ensure(root, func() (interface{}, error) {
repo, err := r.RepoRootForImportPath(root, false)
if err != nil {
return nil, err
}
return remoteValue{remote: repo.Repo, vcs: repo.VCS.Cmd}, nil
})
if err != nil {
return "", "", err
}
value := v.(remoteValue)
return value.remote, value.vcs, nil
}
// Head returns the most recent commit id on the default branch and latest
// version tag for the given remote repository. The tag "" is returned if
// no latest version was found.
//
// TODO(jayconrod): support VCS other than git.
// TODO(jayconrod): support version tags. "" is always returned.
func (r *RemoteCache) Head(remote, vcs string) (commit, tag string, err error) {
if vcs != "git" {
return "", "", fmt.Errorf("could not locate recent commit in repo %q with unknown version control scheme %q", remote, vcs)
}
v, err := r.head.ensure(remote, func() (interface{}, error) {
commit, err := r.HeadCmd(remote, vcs)
if err != nil {
return nil, err
}
return headValue{commit: commit}, nil
})
if err != nil {
return "", "", err
}
value := v.(headValue)
return value.commit, value.tag, nil
}
func defaultHeadCmd(remote, vcs string) (string, error) {
switch vcs {
case "local":
return "", nil
case "git":
// Old versions of git ls-remote exit with code 129 when "--" is passed.
// We'll try to validate the argument here instead.
if strings.HasPrefix(remote, "-") {
return "", fmt.Errorf("remote must not start with '-': %q", remote)
}
cmd := exec.Command("git", "ls-remote", remote, "HEAD")
out, err := cmd.Output()
if err != nil {
return "", err
}
ix := bytes.IndexByte(out, '\t')
if ix < 0 {
return "", fmt.Errorf("could not parse output for git ls-remote for %q", remote)
}
return string(out[:ix]), nil
default:
return "", fmt.Errorf("unknown version control system: %s", vcs)
}
}
// get retrieves a value associated with the given key from the cache. ok will
// be true if the key exists in the cache, even if it's in the process of
// being fetched.
func (m *remoteCacheMap) get(key string) (value interface{}, ok bool, err error) {
m.mu.Lock()
e, ok := m.cache[key]
m.mu.Unlock()
if !ok {
return nil, ok, nil
}
if e.ready != nil {
<-e.ready
}
return e.value, ok, e.err
}
// ensure retreives a value associated with the given key from the cache. If
// the key does not exist in the cache, the load function will be called,
// and its result will be associated with the key. The load function will not
// be called more than once for any key.
func (m *remoteCacheMap) ensure(key string, load func() (interface{}, error)) (interface{}, error) {
m.mu.Lock()
e, ok := m.cache[key]
if !ok {
e = &remoteCacheEntry{ready: make(chan struct{})}
m.cache[key] = e
m.mu.Unlock()
e.value, e.err = load()
close(e.ready)
} else {
m.mu.Unlock()
if e.ready != nil {
<-e.ready
}
}
return e.value, e.err
}

View File

@@ -1,190 +0,0 @@
/* Copyright 2017 The Bazel Authors. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package repos
import (
"fmt"
"os"
"path/filepath"
"sort"
"strings"
"github.com/bazelbuild/bazel-gazelle/internal/rule"
)
// Repo describes an external repository rule declared in a Bazel
// WORKSPACE file.
type Repo struct {
// Name is the value of the "name" attribute of the repository rule.
Name string
// GoPrefix is the portion of the Go import path for the root of this
// repository. Usually the same as Remote.
GoPrefix string
// Commit is the revision at which a repository is checked out (for example,
// a Git commit id).
Commit string
// Tag is the name of the version at which a repository is checked out.
Tag string
// Remote is the URL the repository can be cloned or checked out from.
Remote string
// VCS is the version control system used to check out the repository.
// May also be "http" for HTTP archives.
VCS string
}
type byName []Repo
func (s byName) Len() int { return len(s) }
func (s byName) Less(i, j int) bool { return s[i].Name < s[j].Name }
func (s byName) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
type lockFileFormat int
const (
unknownFormat lockFileFormat = iota
depFormat
)
var lockFileParsers = map[lockFileFormat]func(string) ([]Repo, error){
depFormat: importRepoRulesDep,
}
// ImportRepoRules reads the lock file of a vendoring tool and returns
// a list of equivalent repository rules that can be merged into a WORKSPACE
// file. The format of the file is inferred from its basename. Currently,
// only Gopkg.lock is supported.
func ImportRepoRules(filename string) ([]*rule.Rule, error) {
format := getLockFileFormat(filename)
if format == unknownFormat {
return nil, fmt.Errorf(`%s: unrecognized lock file format. Expected "Gopkg.lock"`, filename)
}
parser := lockFileParsers[format]
repos, err := parser(filename)
if err != nil {
return nil, fmt.Errorf("error parsing %q: %v", filename, err)
}
sort.Stable(byName(repos))
rules := make([]*rule.Rule, 0, len(repos))
for _, repo := range repos {
rules = append(rules, GenerateRule(repo))
}
return rules, nil
}
func getLockFileFormat(filename string) lockFileFormat {
switch filepath.Base(filename) {
case "Gopkg.lock":
return depFormat
default:
return unknownFormat
}
}
// GenerateRule returns a repository rule for the given repository that can
// be written in a WORKSPACE file.
func GenerateRule(repo Repo) *rule.Rule {
r := rule.NewRule("go_repository", repo.Name)
r.SetAttr("commit", repo.Commit)
r.SetAttr("importpath", repo.GoPrefix)
if repo.Remote != "" {
r.SetAttr("remote", repo.Remote)
}
if repo.VCS != "" {
r.SetAttr("vcs", repo.VCS)
}
return r
}
// FindExternalRepo attempts to locate the directory where Bazel has fetched
// the external repository with the given name. An error is returned if the
// repository directory cannot be located.
func FindExternalRepo(repoRoot, name string) (string, error) {
// See https://docs.bazel.build/versions/master/output_directories.html
// for documentation on Bazel directory layout.
// We expect the bazel-out symlink in the workspace root directory to point to
// <output-base>/execroot/<workspace-name>/bazel-out
// We expect the external repository to be checked out at
// <output-base>/external/<name>
// Note that users can change the prefix for most of the Bazel symlinks with
// --symlink_prefix, but this does not include bazel-out.
externalPath := strings.Join([]string{repoRoot, "bazel-out", "..", "..", "..", "external", name}, string(os.PathSeparator))
cleanPath, err := filepath.EvalSymlinks(externalPath)
if err != nil {
return "", err
}
st, err := os.Stat(cleanPath)
if err != nil {
return "", err
}
if !st.IsDir() {
return "", fmt.Errorf("%s: not a directory", externalPath)
}
return cleanPath, nil
}
// ListRepositories extracts metadata about repositories declared in a
// WORKSPACE file.
//
// The set of repositories returned is necessarily incomplete, since we don't
// evaluate the file, and repositories may be declared in macros in other files.
func ListRepositories(workspace *rule.File) []Repo {
var repos []Repo
for _, r := range workspace.Rules {
name := r.Name()
if name == "" {
continue
}
var repo Repo
switch r.Kind() {
case "go_repository":
// TODO(jayconrod): extract other fields needed by go_repository.
// Currently, we don't use the result of this function to produce new
// go_repository rules, so it doesn't matter.
goPrefix := r.AttrString("importpath")
revision := r.AttrString("commit")
remote := r.AttrString("remote")
vcs := r.AttrString("vcs")
if goPrefix == "" {
continue
}
repo = Repo{
Name: name,
GoPrefix: goPrefix,
Commit: revision,
Remote: remote,
VCS: vcs,
}
// TODO(jayconrod): infer from {new_,}git_repository, {new_,}http_archive,
// local_repository.
default:
continue
}
repos = append(repos, repo)
}
// TODO(jayconrod): look for directives that describe repositories that
// aren't declared in the top-level of WORKSPACE (e.g., behind a macro).
return repos
}

View File

@@ -1,29 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["index.go"],
importmap = "sigs.k8s.io/kind/vendor/github.com/bazelbuild/bazel-gazelle/internal/resolve",
importpath = "github.com/bazelbuild/bazel-gazelle/internal/resolve",
visibility = ["//vendor/github.com/bazelbuild/bazel-gazelle:__subpackages__"],
deps = [
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/config:go_default_library",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/label:go_default_library",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/repos:go_default_library",
"//vendor/github.com/bazelbuild/bazel-gazelle/internal/rule:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -1,246 +0,0 @@
/* Copyright 2018 The Bazel Authors. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package resolve
import (
"log"
"github.com/bazelbuild/bazel-gazelle/internal/config"
"github.com/bazelbuild/bazel-gazelle/internal/label"
"github.com/bazelbuild/bazel-gazelle/internal/repos"
"github.com/bazelbuild/bazel-gazelle/internal/rule"
)
// ImportSpec describes a library to be imported. Imp is an import string for
// the library. Lang is the language in which the import string appears (this
// should match Resolver.Name).
type ImportSpec struct {
Lang, Imp string
}
// Resolver is an interface that language extensions can implement to resolve
// dependencies in rules they generate.
type Resolver interface {
// Name returns the name of the language. This should be a prefix of the
// kinds of rules generated by the language, e.g., "go" for the Go extension
// since it generates "go_library" rules.
Name() string
// Imports returns a list of ImportSpecs that can be used to import the rule
// r. This is used to populate RuleIndex.
//
// If nil is returned, the rule will not be indexed. If any non-nil slice is
// returned, including an empty slice, the rule will be indexed.
Imports(c *config.Config, r *rule.Rule, f *rule.File) []ImportSpec
// Embeds returns a list of labels of rules that the given rule embeds. If
// a rule is embedded by another importable rule of the same language, only
// the embedding rule will be indexed. The embedding rule will inherit
// the imports of the embedded rule.
Embeds(r *rule.Rule, from label.Label) []label.Label
// Resolve translates imported libraries for a given rule into Bazel
// dependencies. A list of imported libraries is typically stored in a
// private attribute of the rule when it's generated (this interface doesn't
// dictate how that is stored or represented). Resolve generates a "deps"
// attribute (or the appropriate language-specific equivalent) for each
// import according to language-specific rules and heuristics.
Resolve(c *config.Config, ix *RuleIndex, rc *repos.RemoteCache, r *rule.Rule, from label.Label)
}
// RuleIndex is a table of rules in a workspace, indexed by label and by
// import path. Used by Resolver to map import paths to labels.
type RuleIndex struct {
rules []*ruleRecord
labelMap map[label.Label]*ruleRecord
importMap map[ImportSpec][]*ruleRecord
kindToResolver map[string]Resolver
}
// ruleRecord contains information about a rule relevant to import indexing.
type ruleRecord struct {
rule *rule.Rule
label label.Label
// importedAs is a list of ImportSpecs by which this rule may be imported.
// Used to build a map from ImportSpecs to ruleRecords.
importedAs []ImportSpec
// embeds is the transitive closure of labels for rules that this rule embeds
// (as determined by the Embeds method). This only includes rules in the same
// language (i.e., it includes a go_library embedding a go_proto_library, but
// not a go_proto_library embedding a proto_library).
embeds []label.Label
// embedded indicates whether another rule of the same language embeds this
// rule. Embedded rules should not be indexed.
embedded bool
didCollectEmbeds bool
}
// NewRuleIndex creates a new index.
//
// kindToResolver is a map from rule kinds (for example, "go_library") to
// Resolvers that support those kinds.
func NewRuleIndex(kindToResolver map[string]Resolver) *RuleIndex {
return &RuleIndex{
labelMap: make(map[label.Label]*ruleRecord),
kindToResolver: kindToResolver,
}
}
// AddRule adds a rule r to the index. The rule will only be indexed if there
// is a known resolver for the rule's kind and Resolver.Imports returns a
// non-nil slice.
//
// AddRule may only be called before Finish.
func (ix *RuleIndex) AddRule(c *config.Config, r *rule.Rule, f *rule.File) {
var imps []ImportSpec
if rslv, ok := ix.kindToResolver[r.Kind()]; ok {
imps = rslv.Imports(c, r, f)
}
// If imps == nil, the rule is not importable. If imps is the empty slice,
// it may still be importable if it embeds importable libraries.
if imps == nil {
return
}
record := &ruleRecord{
rule: r,
label: label.New(c.RepoName, f.Pkg, r.Name()),
importedAs: imps,
}
if _, ok := ix.labelMap[record.label]; ok {
log.Printf("multiple rules found with label %s", record.label)
return
}
ix.rules = append(ix.rules, record)
ix.labelMap[record.label] = record
}
// Finish constructs the import index and performs any other necessary indexing
// actions after all rules have been added. This step is necessary because
// a rule may be indexed differently based on what rules are added later.
//
// Finish must be called after all AddRule calls and before any
// FindRulesByImport calls.
func (ix *RuleIndex) Finish() {
for _, r := range ix.rules {
ix.collectEmbeds(r)
}
ix.buildImportIndex()
}
func (ix *RuleIndex) collectEmbeds(r *ruleRecord) {
if r.didCollectEmbeds {
return
}
r.didCollectEmbeds = true
embedLabels := ix.kindToResolver[r.rule.Kind()].Embeds(r.rule, r.label)
r.embeds = embedLabels
for _, e := range embedLabels {
er, ok := ix.findRuleByLabel(e, r.label)
if !ok {
continue
}
ix.collectEmbeds(er)
if ix.kindToResolver[r.rule.Kind()] == ix.kindToResolver[er.rule.Kind()] {
er.embedded = true
r.embeds = append(r.embeds, er.embeds...)
}
r.importedAs = append(r.importedAs, er.importedAs...)
}
}
// buildImportIndex constructs the map used by FindRulesByImport.
func (ix *RuleIndex) buildImportIndex() {
ix.importMap = make(map[ImportSpec][]*ruleRecord)
for _, r := range ix.rules {
if r.embedded {
continue
}
indexed := make(map[ImportSpec]bool)
for _, imp := range r.importedAs {
if indexed[imp] {
continue
}
indexed[imp] = true
ix.importMap[imp] = append(ix.importMap[imp], r)
}
}
}
func (ix *RuleIndex) findRuleByLabel(label label.Label, from label.Label) (*ruleRecord, bool) {
label = label.Abs(from.Repo, from.Pkg)
r, ok := ix.labelMap[label]
return r, ok
}
type FindResult struct {
// Label is the absolute label (including repository and package name) for
// a matched rule.
Label label.Label
Rule *rule.Rule
// Embeds is the transitive closure of labels for rules that the matched
// rule embeds. It may contains duplicates and does not include the label
// for the rule itself.
Embeds []label.Label
}
// FindRulesByImport attempts to resolve an import string to a rule record.
// imp is the import to resolve (which includes the target language). lang is
// the language of the rule with the dependency (for example, in
// go_proto_library, imp will have ProtoLang and lang will be GoLang).
// from is the rule which is doing the dependency. This is used to check
// vendoring visibility and to check for self-imports.
//
// FindRulesByImport returns a list of rules, since any number of rules may
// provide the same import. Callers may need to resolve ambiguities using
// language-specific heuristics.
func (ix *RuleIndex) FindRulesByImport(imp ImportSpec, lang string) []FindResult {
matches := ix.importMap[imp]
results := make([]FindResult, 0, len(matches))
for _, m := range matches {
if ix.kindToResolver[m.rule.Kind()].Name() != lang {
continue
}
results = append(results, FindResult{
Label: m.label,
Rule: m.rule,
Embeds: m.embeds,
})
}
return results
}
// IsSelfImport returns true if the result's label matches the given label
// or the result's rule transitively embeds the rule with the given label.
// Self imports cause cyclic dependencies, so the caller may want to omit
// the dependency or report an error.
func (r FindResult) IsSelfImport(from label.Label) bool {
if from.Equal(r.Label) {
return true
}
for _, e := range r.Embeds {
if from.Equal(e) {
return true
}
}
return false
}

Some files were not shown because too many files have changed in this diff Show More