summaryrefslogtreecommitdiffhomepage
path: root/util/codegen/codegen.go
diff options
context:
space:
mode:
authorBrad Fitzpatrick <bradfitz@tailscale.com>2023-01-02 20:19:33 -0800
committerBrad Fitzpatrick <brad@danga.com>2023-01-02 20:38:32 -0800
commitaad6830df0b68362a5d006b1470e0ed3cd56fe73 (patch)
tree0d57dc6c0d57b764eacfa5db73fa15f66f6b2714 /util/codegen/codegen.go
parentea70aa3d980db1c7bd1912298167e545249c08fa (diff)
downloadtailscale-aad6830df0b68362a5d006b1470e0ed3cd56fe73.tar.xz
tailscale-aad6830df0b68362a5d006b1470e0ed3cd56fe73.zip
util/codegen, all: use latest year, not time.Now, in generated files
Updates #6865 Change-Id: I6b86c646968ebbd4553cf37df5e5612fbf5c5f7d Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Diffstat (limited to 'util/codegen/codegen.go')
-rw-r--r--util/codegen/codegen.go64
1 files changed, 59 insertions, 5 deletions
diff --git a/util/codegen/codegen.go b/util/codegen/codegen.go
index 61ec85de8..0e851a7ea 100644
--- a/util/codegen/codegen.go
+++ b/util/codegen/codegen.go
@@ -6,6 +6,7 @@
package codegen
import (
+ "bufio"
"bytes"
"fmt"
"go/ast"
@@ -13,13 +14,16 @@ import (
"go/types"
"io"
"os"
+ "path/filepath"
"reflect"
+ "regexp"
+ "strconv"
"strings"
- "time"
"golang.org/x/tools/go/packages"
"golang.org/x/tools/imports"
"tailscale.com/util/mak"
+ "tailscale.com/util/must"
)
// LoadTypes returns all named types in pkgName, keyed by their type name.
@@ -104,15 +108,15 @@ func (it *ImportTracker) Write(w io.Writer) {
fmt.Fprintf(w, ")\n\n")
}
-func writeHeader(w io.Writer, tool, pkg string) {
- fmt.Fprintf(w, header, time.Now().Year(), tool, pkg)
+func writeHeader(w io.Writer, tool, pkg string, copyrightYear int) {
+ fmt.Fprintf(w, header, copyrightYear, tool, pkg)
}
// WritePackageFile adds a file with the provided imports and contents to package.
// The tool param is used to identify the tool that generated package file.
-func WritePackageFile(tool string, pkg *packages.Package, path string, it *ImportTracker, contents *bytes.Buffer) error {
+func WritePackageFile(tool string, pkg *packages.Package, path string, copyrightYear int, it *ImportTracker, contents *bytes.Buffer) error {
buf := new(bytes.Buffer)
- writeHeader(buf, tool, pkg.Name)
+ writeHeader(buf, tool, pkg.Name, copyrightYear)
it.Write(buf)
if _, err := buf.Write(contents.Bytes()); err != nil {
return err
@@ -263,3 +267,53 @@ func IsViewType(typ types.Type) bool {
}
return t.Field(0).Name() == "ж"
}
+
+// CopyrightYear reports the greatest copyright year in non-generated *.go files
+// in the current directory, for use in the copyright line of generated code.
+//
+// It panics on I/O error, as it's assumed this is only being used by "go
+// generate" or GitHub actions.
+//
+// TODO(bradfitz,dgentry): determine what heuristic to use for all this: latest
+// year, earliest, none? don't list years at all? IANAL. Get advice of others.
+// For now we just want to unbreak the tree. See Issue 6865.
+func CopyrightYear(dir string) (year int) {
+ files, err := os.ReadDir(dir)
+ if err != nil {
+ panic(err)
+ }
+ rxYear := regexp.MustCompile(`^// Copyright \(c\) (20\d{2}) `)
+ rxGenerated := regexp.MustCompile(`^// Code generated .* DO NOT EDIT\.$`)
+Files:
+ for _, f := range files {
+ name := f.Name()
+ if f.IsDir() ||
+ !strings.HasSuffix(name, ".go") ||
+ strings.HasSuffix(name, "_clone.go") ||
+ strings.HasSuffix(name, "_view.go") ||
+ strings.HasSuffix(name, "_test.go") {
+ continue
+ }
+ src, err := os.ReadFile(filepath.Join(dir, name))
+ if err != nil {
+ panic(err)
+ }
+ bs := bufio.NewScanner(bytes.NewReader(src))
+ for bs.Scan() {
+ line := bs.Bytes()
+ if m := rxYear.FindSubmatch(line); m != nil {
+ if y := must.Get(strconv.Atoi(string(m[1]))); y > year {
+ year = y
+ }
+ continue
+ }
+ if rxGenerated.Match(line) {
+ continue Files
+ }
+ }
+ }
+ if year == 0 {
+ panic("no Copyright line found in any *.go file in " + dir)
+ }
+ return year
+}