diff options
Diffstat (limited to 'file.go')
| -rw-r--r-- | file.go | 64 |
1 files changed, 49 insertions, 15 deletions
@@ -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 += ` ` } |
