diff options
| author | Shulhan <ms@kilabit.info> | 2026-01-13 21:08:26 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2026-01-14 04:10:44 +0700 |
| commit | a2bfa5ec9539f9063e33519e245ae00193783750 (patch) | |
| tree | dd15bf22d9b7df7b2079103fbd248c0eb717b59e /file.go | |
| parent | 3bc8f7ea570c726d88f4e0d31910b9eec999ce46 (diff) | |
| download | spdxconv-a2bfa5ec9539f9063e33519e245ae00193783750.tar.xz | |
all: get the copyright year from git history
If the line that match with pattern on match-copyright does not contains
year, or there is no match, try to get the year from the first commit of
the file using "git log --follow ..." command.
If no commit history or its not using git, use default copyright year from
configuration.
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 += ` ` } |
