-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
infra: Add copyright headers check, copyright headers (#18)
This change adds: * a Go tool to check for copyright headers * a Github job to run the check in presubmit and postsubmit * copyright headers to all files, to satisfy the check Because this check necessarily depends on all source files, it can't be implemented as a bazel test, so it is instead designed to be invoked via `bazel run` (depends on an environment var that locates the workspace root). Go was chosen over bash to avoid complicated pipelines and array/associative array bash syntax. Tested: Wrote the tool first; it identified all the source files in the repo, which were resolved either by adding a header, or by adding an exception inside the `generatedFiles` var.
- Loading branch information
1 parent
e78edce
commit ddfce52
Showing
22 changed files
with
454 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
load("@rules_go//go:def.bzl", "go_binary", "go_library") | ||
|
||
go_library( | ||
name = "check_copyright_headers_lib", | ||
srcs = ["main.go"], | ||
importpath = "github.com/EngFlow/auth/infra/internal/check_copyright_headers", | ||
visibility = ["//infra:__subpackages__"], | ||
) | ||
|
||
go_binary( | ||
name = "check_copyright_headers", | ||
embed = [":check_copyright_headers_lib"], | ||
visibility = ["//infra:__subpackages__"], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
// Copyright 2024 EngFlow Inc. 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 ( | ||
"bufio" | ||
"errors" | ||
"fmt" | ||
"os" | ||
"os/exec" | ||
"path/filepath" | ||
"regexp" | ||
"sort" | ||
"strings" | ||
) | ||
|
||
var ( | ||
skipRegexps = []*regexp.Regexp{ | ||
regexp.MustCompile(`^go\.mod$`), | ||
regexp.MustCompile(`^go\.sum$`), | ||
regexp.MustCompile(`^LICENSE$`), | ||
regexp.MustCompile(`^MODULE\.bazel\.lock$`), | ||
regexp.MustCompile(`^MODULE\.bazel$`), | ||
regexp.MustCompile(`^README.md$`), | ||
regexp.MustCompile(`^WORKSPACE$`), | ||
regexp.MustCompile(`(/|^)BUILD$`), | ||
regexp.MustCompile(`^\.bazelrc$`), | ||
regexp.MustCompile(`^\.gitignore$`), | ||
regexp.MustCompile(`\.bzl$`), | ||
} | ||
copyrightRegexp = regexp.MustCompile(`^(#|//) Copyright [0-9-]+ EngFlow Inc\.`) | ||
) | ||
|
||
type checkerFunc func(string) bool | ||
|
||
// listSourceFiles returns the list of files that git cares about in the current | ||
// commit. | ||
func listSourceFiles(repoRoot string) ([]string, error) { | ||
cmd := exec.Command("git", "ls-tree", "-r", "--name-only", "HEAD") | ||
cmd.Dir = repoRoot | ||
output, err := cmd.Output() | ||
if err != nil { | ||
return nil, fmt.Errorf("`git ls-tree` failed: %w", err) | ||
} | ||
return strings.Split(strings.TrimSpace(string(output)), "\n"), nil | ||
} | ||
|
||
// filterStrings returns strings in `universe` that don't match any regexps in | ||
// `remove`. | ||
func filterStrings(universe []string, remove []*regexp.Regexp) []string { | ||
var filtered []string | ||
nextStr: | ||
for _, s := range universe { | ||
for _, r := range remove { | ||
if r.MatchString(s) { | ||
continue nextStr | ||
} | ||
} | ||
filtered = append(filtered, s) | ||
} | ||
return filtered | ||
} | ||
|
||
// checkCopyright runs the supplied checker on each line of the file, returning | ||
// an error if the checker never returns true. | ||
func checkCopyright(path string, checker checkerFunc) error { | ||
f, err := os.Open(path) | ||
if err != nil { | ||
return err | ||
} | ||
defer f.Close() | ||
scanner := bufio.NewScanner(f) | ||
for scanner.Scan() { | ||
if checker(scanner.Text()) { | ||
return nil | ||
} | ||
} | ||
return fmt.Errorf("%s: missing copyright header", path) | ||
} | ||
|
||
func run() error { | ||
workspaceRoot := os.Getenv("BUILD_WORKSPACE_DIRECTORY") | ||
if workspaceRoot == "" { | ||
return fmt.Errorf("$BUILD_WORKSPACE_DIRECTORY is not set; please run this script via `bazel run`") | ||
} | ||
srcFiles, err := listSourceFiles(workspaceRoot) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
srcFiles = filterStrings(srcFiles, skipRegexps) | ||
|
||
var errs []error | ||
for _, f := range srcFiles { | ||
if err := checkCopyright(filepath.Join(workspaceRoot, f), copyrightRegexp.MatchString); err != nil { | ||
errs = append(errs, err) | ||
continue | ||
} | ||
} | ||
|
||
if len(errs) == 0 { | ||
return nil | ||
} | ||
|
||
sort.Slice(errs, func(i, j int) bool { return errs[i].Error() < errs[j].Error() }) | ||
return fmt.Errorf("copyright header check failed:\n%v", errors.Join(errs...)) | ||
} | ||
|
||
func main() { | ||
if err := run(); err != nil { | ||
fmt.Fprintf(os.Stderr, "ERROR: %v\n", err) | ||
os.Exit(1) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.