aboutsummaryrefslogtreecommitdiff
path: root/file.go
diff options
context:
space:
mode:
Diffstat (limited to 'file.go')
-rw-r--r--file.go64
1 files changed, 49 insertions, 15 deletions
diff --git a/file.go b/file.go
index 742290d..11d2154 100644
--- a/file.go
+++ b/file.go
@@ -6,11 +6,14 @@ package spdxconv
import (
"bytes"
"fmt"
+ "log"
"os"
"path/filepath"
"regexp"
"slices"
+ "strconv"
"strings"
+ "time"
libos "git.sr.ht/~shulhan/pakakeh.go/lib/os"
)
@@ -20,17 +23,16 @@ const (
valDefault = `default` // Use the default value from configuration.
valExist = `exist` // The license/copyright exist in the file.
valMatch = `match` // One of the pattern in match-xxx found in file.
- valUnknown = `unknown`
)
// REUSE-IgnoreStart
// reLicenseID regex to detect SPDX license identifier with or without
// comment prefix.
-var reLicenseID = regexp.MustCompile(`^(//+|#+|/\*+|<!--+)?\s?SPDX-License-Identifier:\s*(.*)\s*$`)
+var reLicenseID = regexp.MustCompile(`^(//+|#+|/\*+|<!--+|--+)?\s?SPDX-License-Identifier:\s*(.*)\s*$`)
// reCopyrightText regex to detect SPDX copyright text.
-var reCopyrightText = regexp.MustCompile(`^(//+|#+|/\*+|<!--+)?\s?SPDX-FileCopyrightText:\s*(.*)\s*$`)
+var reCopyrightText = regexp.MustCompile(`^(//+|#+|/\*+|<!--+|--+)?\s?SPDX-FileCopyrightText:\s*(.*)\s*$`)
// REUSE-IgnoreEnd
@@ -41,8 +43,6 @@ type file struct {
path string
// commentPrefix used as prefix to SPDX identifier.
- // The comment prefix is detected automatically from the first N
- // lines of file.
commentPrefix string
commentSuffix string
@@ -77,11 +77,8 @@ func newFile(path string, maxLine int) (f *file, err error) {
}
f = &file{
- path: path,
- licenseID: valDefault,
- copyrightYear: valUnknown,
- copyrightText: valDefault,
- isBinary: libos.IsBinaryStream(content),
+ path: path,
+ isBinary: libos.IsBinaryStream(content),
}
if f.isBinary {
return f, nil
@@ -125,6 +122,7 @@ func (f *file) scan(conv *SPDXConv) {
}
f.scanLicenseID(conv)
f.scanCopyrightText(conv)
+ f.getYearFromSCM(conv)
}
// detectComment get comment prefix and suffix using the "match-file-comment"
@@ -149,6 +147,7 @@ func (f *file) detectComment(cfg *config) {
}
func (f *file) scanLicenseID(conv *SPDXConv) {
+ f.licenseID = valDefault
for _, cml := range conv.cfg.MatchLicense {
for x, line := range f.topLines {
if reLicenseID.Match(line) {
@@ -175,10 +174,10 @@ func (f *file) scanLicenseID(conv *SPDXConv) {
}
}
}
- f.licenseID = valDefault
}
func (f *file) scanCopyrightText(conv *SPDXConv) {
+ f.copyrightText = valDefault
for _, cmc := range conv.cfg.MatchCopyright {
for x, line := range f.topLines {
if reCopyrightText.Match(line) {
@@ -207,7 +206,45 @@ func (f *file) scanCopyrightText(conv *SPDXConv) {
}
}
}
- f.copyrightText = valDefault
+}
+
+func (f *file) getYearFromSCM(conv *SPDXConv) {
+ if f.copyrightText == valExist {
+ // SPDX for copyright exist, skip it. Even though maybe there
+ // is no year.
+ return
+ }
+ if f.copyrightYear != `` {
+ return
+ }
+ var logp = `getYearFromSCM`
+
+ f.copyrightYear = conv.cfg.CopyrightYear
+
+ logs, err := conv.scm.LogFollow(f.path, ``)
+ if err != nil {
+ log.Printf(`%s %s: %s`, logp, f.path, err)
+ return
+ }
+ if len(logs) == 0 {
+ log.Printf(`%s %s: empty commit history`, logp, f.path)
+ return
+ }
+
+ first_commit := logs[len(logs)-1]
+ fields := strings.Split(first_commit, `,`)
+ if len(fields) < 2 {
+ log.Printf(`%s %s: cannot parse commit log %q`, logp, f.path, first_commit)
+ return
+ }
+
+ sec, err := strconv.ParseInt(fields[1], 10, 64)
+ if err != nil {
+ log.Printf(`%s %s: cannot parse commit timestamp: %s`, logp, f.path, err)
+ return
+ }
+
+ f.copyrightYear = strconv.Itoa(time.Unix(sec, 0).Year())
}
// apply the SPDX identifier to file.
@@ -242,9 +279,6 @@ func (f *file) apply(conv *SPDXConv) (err error) {
}
f.topLines = slices.Insert(f.topLines, f.idxLicenseID, rawline)
- if f.copyrightYear == valUnknown {
- f.copyrightYear = conv.cfg.CopyrightYear
- }
if f.copyrightYear != `` {
f.copyrightYear += ` `
}