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>
pull/6933/head
Brad Fitzpatrick 2 years ago committed by Brad Fitzpatrick
parent ea70aa3d98
commit aad6830df0

@ -80,7 +80,7 @@ func main() {
w("}") w("}")
} }
cloneOutput := pkg.Name + "_clone.go" cloneOutput := pkg.Name + "_clone.go"
if err := codegen.WritePackageFile("tailscale.com/cmd/cloner", pkg, cloneOutput, it, buf); err != nil { if err := codegen.WritePackageFile("tailscale.com/cmd/cloner", pkg, cloneOutput, codegen.CopyrightYear("."), it, buf); err != nil {
log.Fatal(err) log.Fatal(err)
} }
} }

@ -384,7 +384,7 @@ func main() {
genView(buf, it, typ, pkg.Types) genView(buf, it, typ, pkg.Types)
} }
out := pkg.Name + "_view.go" out := pkg.Name + "_view.go"
if err := codegen.WritePackageFile("tailscale/cmd/viewer", pkg, out, it, buf); err != nil { if err := codegen.WritePackageFile("tailscale/cmd/viewer", pkg, out, codegen.CopyrightYear("."), it, buf); err != nil {
log.Fatal(err) log.Fatal(err)
} }
if runCloner { if runCloner {

@ -1,4 +1,4 @@
// Copyright (c) 2022 Tailscale Inc & AUTHORS All rights reserved. // Copyright (c) 2020 Tailscale Inc & AUTHORS All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.

@ -1,4 +1,4 @@
// Copyright (c) 2022 Tailscale Inc & AUTHORS All rights reserved. // Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.

@ -1,4 +1,4 @@
// Copyright (c) 2022 Tailscale Inc & AUTHORS All rights reserved. // Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.

@ -1,4 +1,4 @@
// Copyright (c) 2022 Tailscale Inc & AUTHORS All rights reserved. // Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.

@ -1,4 +1,4 @@
// Copyright (c) 2022 Tailscale Inc & AUTHORS All rights reserved. // Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.

@ -6,6 +6,7 @@
package codegen package codegen
import ( import (
"bufio"
"bytes" "bytes"
"fmt" "fmt"
"go/ast" "go/ast"
@ -13,13 +14,16 @@ import (
"go/types" "go/types"
"io" "io"
"os" "os"
"path/filepath"
"reflect" "reflect"
"regexp"
"strconv"
"strings" "strings"
"time"
"golang.org/x/tools/go/packages" "golang.org/x/tools/go/packages"
"golang.org/x/tools/imports" "golang.org/x/tools/imports"
"tailscale.com/util/mak" "tailscale.com/util/mak"
"tailscale.com/util/must"
) )
// LoadTypes returns all named types in pkgName, keyed by their type name. // 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") fmt.Fprintf(w, ")\n\n")
} }
func writeHeader(w io.Writer, tool, pkg string) { func writeHeader(w io.Writer, tool, pkg string, copyrightYear int) {
fmt.Fprintf(w, header, time.Now().Year(), tool, pkg) fmt.Fprintf(w, header, copyrightYear, tool, pkg)
} }
// WritePackageFile adds a file with the provided imports and contents to package. // 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. // 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) buf := new(bytes.Buffer)
writeHeader(buf, tool, pkg.Name) writeHeader(buf, tool, pkg.Name, copyrightYear)
it.Write(buf) it.Write(buf)
if _, err := buf.Write(contents.Bytes()); err != nil { if _, err := buf.Write(contents.Bytes()); err != nil {
return err return err
@ -263,3 +267,53 @@ func IsViewType(typ types.Type) bool {
} }
return t.Field(0).Name() == "ж" 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
}

@ -1,4 +1,4 @@
// Copyright (c) 2022 Tailscale Inc & AUTHORS All rights reserved. // Copyright (c) 2020 Tailscale Inc & AUTHORS All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.

@ -1,4 +1,4 @@
// Copyright (c) 2022 Tailscale Inc & AUTHORS All rights reserved. // Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.

Loading…
Cancel
Save