diff --git a/internal/check/check.go b/internal/check/check.go new file mode 100644 index 0000000..e073f58 --- /dev/null +++ b/internal/check/check.go @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: Unlicense + +package main + +import ( + "bufio" + "errors" + "fmt" + "io/fs" + "os" + "path/filepath" + "regexp" + "strings" +) + +var goSpdxHeader = `// SPDX-License-Identifier: Unlicense` +var tmplSpdxHeader = `{{/* SPDX-License-Identifier: Unlicense */` + +type MissingSPDXError struct { + Name string +} + +func (m MissingSPDXError) Error() string { + return fmt.Sprintf("missing or incorrect SPDX header: %s", m.Name) +} + +func checkFileSPDX(header string, name string) error { + f, err := os.Open(name) + if err != nil { + return err + } + defer f.Close() + + r := bufio.NewReader(f) + pattern := `(?m:^` + regexp.QuoteMeta(header) + `)` + matched, err := regexp.MatchReader(pattern, r) + if err != nil { + return err + } + if !matched { + return MissingSPDXError{Name: name} + } + return nil +} + +func walkSPDX(header string, extension string) error { + var errs []error + filepath.WalkDir(".", func(path string, d fs.DirEntry, err error) error { + if path != "." && strings.HasPrefix(path, ".") { + if d.IsDir() { + return filepath.SkipDir + } + return nil + } + if err != nil { + errs = append(errs, err) + return nil + } + + if filepath.Ext(path) != extension { + return nil + } + errs = append(errs, checkFileSPDX(header, path)) + return nil + }) + return errors.Join(errs...) +} + +func checkSPDX() error { + err := errors.Join( + walkSPDX(goSpdxHeader, ".go"), + walkSPDX(tmplSpdxHeader, ".tmpl"), + ) + if err != nil { + return fmt.Errorf("Check SPDX Headers:\n%w", err) + } + return nil +} + +func run() error { + return checkSPDX() +} + +func main() { + err := run() + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} diff --git a/state_test.go b/state_test.go index 3a64cbe..b8e9b0d 100644 --- a/state_test.go +++ b/state_test.go @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Unlicense + package gigaparsec_test import (