build: add nogo for static validation

PiperOrigin-RevId: 257297820
This commit is contained in:
Adin Scannell 2019-07-09 16:42:54 -07:00 committed by gVisor bot
parent cceef9d2cf
commit dea3cb92f2
11 changed files with 111 additions and 14 deletions

14
BUILD
View File

@ -1,6 +1,6 @@
package(licenses = ["notice"]) # Apache 2.0
load("@io_bazel_rules_go//go:def.bzl", "go_path")
load("@io_bazel_rules_go//go:def.bzl", "go_path", "nogo")
load("@bazel_gazelle//:def.bzl", "gazelle")
# The sandbox filegroup is used for sandbox-internal dependencies.
@ -29,3 +29,15 @@ go_path(
# To update the WORKSPACE from go.mod, use:
# bazel run //:gazelle -- update-repos -from_file=go.mod
gazelle(name = "gazelle")
# nogo applies checks to all Go source in this repository, enforcing code
# guidelines and restrictions. Note that the tool libraries themselves should
# live in the tools subdirectory (unless they are standard).
nogo(
name = "nogo",
config = "tools/nogo.js",
visibility = ["//visibility:public"],
deps = [
"//tools/checkunsafe",
],
)

View File

@ -20,7 +20,10 @@ load("@io_bazel_rules_go//go:deps.bzl", "go_rules_dependencies", "go_register_to
go_rules_dependencies()
go_register_toolchains(go_version = "1.12.6")
go_register_toolchains(
go_version = "1.12.6",
nogo = "@//:nogo",
)
load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies", "go_repository")
@ -141,6 +144,12 @@ go_repository(
importpath = "golang.org/x/sys",
)
go_repository(
name = "org_golang_x_tools",
commit = "aa82965741a9fecd12b026fbb3d3c6ed3231b8f8",
importpath = "golang.org/x/tools",
)
go_repository(
name = "com_github_google_btree",
importpath = "github.com/google/btree",

View File

@ -31,7 +31,7 @@ go_template_instance(
go_template_instance(
name = "seqatomic_taskgoroutineschedinfo",
out = "seqatomic_taskgoroutineschedinfo.go",
out = "seqatomic_taskgoroutineschedinfo_unsafe.go",
package = "kernel",
suffix = "TaskGoroutineSchedInfo",
template = "//third_party/gvsync:generic_seqatomic",
@ -112,7 +112,7 @@ go_library(
"ptrace_arm64.go",
"rseq.go",
"seccomp.go",
"seqatomic_taskgoroutineschedinfo.go",
"seqatomic_taskgoroutineschedinfo_unsafe.go",
"session_list.go",
"sessions.go",
"signal.go",

View File

@ -5,7 +5,7 @@ load("//tools/go_stateify:defs.bzl", "go_library")
go_template_instance(
name = "atomicptr_credentials",
out = "atomicptr_credentials.go",
out = "atomicptr_credentials_unsafe.go",
package = "auth",
suffix = "Credentials",
template = "//third_party/gvsync:generic_atomicptr",
@ -45,7 +45,7 @@ go_template_instance(
go_library(
name = "auth",
srcs = [
"atomicptr_credentials.go",
"atomicptr_credentials_unsafe.go",
"auth.go",
"capability_set.go",
"context.go",

View File

@ -5,7 +5,7 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test")
go_template_instance(
name = "atomicptr_bucket",
out = "atomicptr_bucket.go",
out = "atomicptr_bucket_unsafe.go",
package = "futex",
suffix = "Bucket",
template = "//third_party/gvsync:generic_atomicptr",
@ -29,7 +29,7 @@ go_template_instance(
go_library(
name = "futex",
srcs = [
"atomicptr_bucket.go",
"atomicptr_bucket_unsafe.go",
"futex.go",
"waiter_list.go",
],

View File

@ -6,7 +6,7 @@ load("//tools/go_generics:defs.bzl", "go_template_instance")
go_template_instance(
name = "seqatomic_parameters",
out = "seqatomic_parameters.go",
out = "seqatomic_parameters_unsafe.go",
package = "time",
suffix = "Parameters",
template = "//third_party/gvsync:generic_seqatomic",
@ -27,7 +27,7 @@ go_library(
"parameters.go",
"sampler.go",
"sampler_unsafe.go",
"seqatomic_parameters.go",
"seqatomic_parameters_unsafe.go",
"tsc_amd64.s",
"tsc_arm64.s",
],

View File

@ -6,7 +6,7 @@ load("//tools/go_generics:defs.bzl", "go_template_instance")
go_template_instance(
name = "atomicptr_int",
out = "atomicptr_int.go",
out = "atomicptr_int_unsafe.go",
package = "atomicptr",
suffix = "Int",
template = "//third_party/gvsync:generic_atomicptr",
@ -17,7 +17,7 @@ go_template_instance(
go_library(
name = "atomicptr",
srcs = ["atomicptr_int.go"],
srcs = ["atomicptr_int_unsafe.go"],
importpath = "gvisor.dev/gvisor/third_party/gvsync/atomicptr",
)

View File

@ -6,7 +6,7 @@ load("//tools/go_generics:defs.bzl", "go_template_instance")
go_template_instance(
name = "seqatomic_int",
out = "seqatomic_int.go",
out = "seqatomic_int_unsafe.go",
package = "seqatomic",
suffix = "Int",
template = "//third_party/gvsync:generic_seqatomic",
@ -17,7 +17,7 @@ go_template_instance(
go_library(
name = "seqatomic",
srcs = ["seqatomic_int.go"],
srcs = ["seqatomic_int_unsafe.go"],
importpath = "gvisor.dev/gvisor/third_party/gvsync/seqatomic",
deps = [
"//third_party/gvsync",

13
tools/checkunsafe/BUILD Normal file
View File

@ -0,0 +1,13 @@
load("@io_bazel_rules_go//go:def.bzl", "go_tool_library")
package(licenses = ["notice"])
go_tool_library(
name = "checkunsafe",
srcs = ["check_unsafe.go"],
importpath = "checkunsafe",
visibility = ["//visibility:public"],
deps = [
"@org_golang_x_tools//go/analysis:go_tool_library",
],
)

View File

@ -0,0 +1,56 @@
// Copyright 2019 The gVisor 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.
// Package checkunsafe allows unsafe imports only in files named appropriately.
package checkunsafe
import (
"fmt"
"path"
"strconv"
"strings"
"golang.org/x/tools/go/analysis"
)
// Analyzer defines the entrypoint.
var Analyzer = &analysis.Analyzer{
Name: "checkunsafe",
Doc: "allows unsafe use only in specified files",
Run: run,
}
func run(pass *analysis.Pass) (interface{}, error) {
for _, f := range pass.Files {
for _, imp := range f.Imports {
// Is this an unsafe import?
pkg, err := strconv.Unquote(imp.Path.Value)
if err != nil || pkg != "unsafe" {
continue
}
// Extract the filename.
filename := pass.Fset.File(imp.Pos()).Name()
// Allow files named _unsafe.go or _test.go to opt out.
if strings.HasSuffix(filename, "_unsafe.go") || strings.HasSuffix(filename, "_test.go") {
continue
}
// Throw the error.
pass.Reportf(imp.Pos(), fmt.Sprintf("package unsafe imported by %s; must end with _unsafe.go", path.Base(filename)))
}
}
return nil, nil
}

7
tools/nogo.js Normal file
View File

@ -0,0 +1,7 @@
{
"checkunsafe": {
"exclude_files": {
"/external/": "not subject to constraint"
}
}
}