// Copyright 2019 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 gen_code_test import ( "testing" "github.com/bazelbuild/rules_go/go/tools/bazel_testing" ) func TestMain(m *testing.M) { bazel_testing.TestMain(m, bazel_testing.Args{ Main: ` -- BUILD.bazel -- load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test", "nogo") go_library( name = "simple", srcs = ["simple.go"], importpath = "simple" ) go_test( name = "simple_test", srcs = ["simple_test.go"], embed = [":simple"] ) nogo( name = "nogo", deps = ["//nocover"], visibility = ["//visibility:public"], ) -- simple.go -- package simple func Foo() string { return "foo" } -- simple_test.go -- package simple import "testing" func TestFoo(t *testing.T) { if actual, expected := Foo(), "foo"; actual != expected { t.Errorf("Foo() should return foo") } } -- nocover/BUILD.bazel -- load("@io_bazel_rules_go//go:def.bzl", "go_library") go_library( name = "nocover", srcs = ["analyzer.go"], importpath = "nocover", visibility = ["//visibility:public"], deps = [ "@org_golang_x_tools//go/analysis", "@org_golang_x_tools//go/analysis/passes/inspect", "@org_golang_x_tools//go/ast/inspector", ], ) -- nocover/analyzer.go -- package nocover import ( "fmt" "go/ast" "strings" "golang.org/x/tools/go/analysis" "golang.org/x/tools/go/analysis/passes/inspect" "golang.org/x/tools/go/ast/inspector" ) var Analyzer = &analysis.Analyzer{ Name: "nocover", Doc: "nocover ensure that source code was not a generated file created by rules_go's coverage implementation", Run: run, Requires: []*analysis.Analyzer{inspect.Analyzer}, } func run(pass *analysis.Pass) (interface{}, error) { inspector := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) inspector.Preorder([]ast.Node{(*ast.ValueSpec)(nil)}, func(node ast.Node) { valueSpec := node.(*ast.ValueSpec) if len(valueSpec.Names) != 1 { return } varName := valueSpec.Names[0].Name // check for coverage variable name that matches this pattern: CoverZ%sZ%dZ%s // see go/tools/builders/compilepkg.go -> coverVar for more information if strings.HasPrefix(varName, "CoverZ") && strings.Count(varName, "Z") >= 3 { pass.Report(analysis.Diagnostic{ Pos: valueSpec.Pos(), End: valueSpec.End(), Message: fmt.Sprintf("variable %s was generated by rules_go", varName), }) } }) return nil, nil } `, Nogo: `@//:nogo`, }) } func TestNogoCoverGenCode(t *testing.T) { if out, err := bazel_testing.BazelOutput("coverage", "//:simple_test"); err != nil { println(string(out)) t.Fatal(err) } }