diff options
| -rw-r--r-- | report.go | 99 | ||||
| -rw-r--r-- | report_test.go | 50 | ||||
| -rw-r--r-- | testdata/loadReport/ok/spdxconv.report | 13 |
3 files changed, 157 insertions, 5 deletions
@@ -6,20 +6,109 @@ package spdxconv import ( "bytes" "encoding/csv" + "errors" "fmt" + "io" "os" + "strconv" + "strings" ) // ReportFile contains the list of files that will be converted or inserted // with SPDX identifiers. const ReportFile = `spdxconv.report` +const reportMetaPrefix = `//spdxconv:` + +const ( + reportGroupRegular = `regular` + reportGroupBinary = `binary` + reportGroupUnknown = `unknown` +) + +const v1FieldsPerRecord = 4 + type report struct { listRegular []*file listBinary []*file listUnknown []*file } +// loadReport load the [ReportFile] from the current directory. +func loadReport() (rep *report, err error) { + var logp = `loadReport` + var content []byte + content, err = os.ReadFile(ReportFile) + if err != nil { + return nil, fmt.Errorf(`%s: %w`, logp, err) + } + + br := bytes.NewReader(content) + csvr := csv.NewReader(br) + csvr.FieldsPerRecord = v1FieldsPerRecord + csvr.ReuseRecord = true + csvr.TrimLeadingSpace = true + + rep = &report{} + var group string + var record []string + var fields []string + var f *file + var n int + + record, err = csvr.Read() + for !errors.Is(err, io.EOF) { + if errors.Is(err, csv.ErrFieldCount) { + if !strings.HasPrefix(record[0], reportMetaPrefix) { + goto next + } + group = strings.TrimPrefix(record[0], reportMetaPrefix) + switch group { + case reportGroupRegular, reportGroupBinary, reportGroupUnknown: + // OK + default: + group = `` + } + goto next + } + + f = &file{ + path: record[0], + copyrightYear: record[2], + } + fields = strings.Split(record[1], `:`) + f.licenseID = fields[0] + if len(fields) == 2 && fields[0] == valExist { + f.idxLicenseID, err = strconv.Atoi(fields[1]) + if err != nil { + return nil, fmt.Errorf(`%s: line %d: %w`, logp, n, err) + } + } + fields = strings.Split(record[3], `:`) + f.copyrightText = fields[0] + if len(fields) == 2 && fields[0] == valExist { + f.idxCopyrightText, err = strconv.Atoi(fields[1]) + if err != nil { + return nil, fmt.Errorf(`%s: line %d: %w`, logp, n, err) + } + } + + switch group { + case reportGroupRegular: + rep.listRegular = append(rep.listRegular, f) + case reportGroupBinary: + rep.listBinary = append(rep.listBinary, f) + case reportGroupUnknown: + rep.listUnknown = append(rep.listUnknown, f) + } + next: + record, err = csvr.Read() + n++ + } + + return rep, nil +} + func newReport() (rep *report) { rep = &report{} return rep @@ -48,13 +137,13 @@ func (rep *report) scan(conv *SPDXConv, listFile []string) (err error) { func (rep *report) write() (err error) { var buf bytes.Buffer - buf.WriteString("//spdxconv:version:v1\n") - buf.WriteString("//spdxconv:header:path,license_id,year,copyright_id\n") + buf.WriteString(reportMetaPrefix + "version:v1\n") + buf.WriteString(reportMetaPrefix + "header:path,license_id,year,copyright_id\n") var csvw = csv.NewWriter(&buf) var record = make([]string, 4) - buf.WriteString("//spdxconv:regular\n") + buf.WriteString(reportMetaPrefix + reportGroupRegular + "\n") for _, file := range rep.listRegular { record[0] = file.path record[1] = file.licenseID @@ -67,7 +156,7 @@ func (rep *report) write() (err error) { } csvw.Flush() - buf.WriteString("//spdxconv:binary\n") + buf.WriteString(reportMetaPrefix + reportGroupBinary + "\n") for _, file := range rep.listBinary { record[0] = file.path record[1] = file.licenseID @@ -80,7 +169,7 @@ func (rep *report) write() (err error) { } csvw.Flush() - buf.WriteString("//spdxconv:unknown\n") + buf.WriteString(reportMetaPrefix + reportGroupUnknown + "\n") for _, file := range rep.listUnknown { record[0] = file.path record[1] = file.licenseID diff --git a/report_test.go b/report_test.go new file mode 100644 index 0000000..74d1f7a --- /dev/null +++ b/report_test.go @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: GPL-3.0-only +// SPDX-FileCopyrightText: 2026 M. Shulhan <ms@kilabit.info> + +package spdxconv + +import ( + "testing" + + "git.sr.ht/~shulhan/pakakeh.go/lib/test" +) + +func TestLoadReport(t *testing.T) { + workDir := `testdata/loadReport/ok/` + t.Chdir(workDir) + + got, err := loadReport() + if err != nil { + t.Fatal(err) + } + exp := &report{ + listRegular: []*file{{ + path: `fileR1`, + licenseID: valDefault, + copyrightYear: valUnknown, + copyrightText: valDefault, + }, { + path: `file R2`, + licenseID: valExist, + idxLicenseID: 1, + copyrightYear: `2024`, + copyrightText: valExist, + idxCopyrightText: -1, + }}, + listBinary: []*file{{ + path: `fileB1`, + licenseID: `BSD-3-Clause`, + copyrightYear: `2000-2026`, + copyrightText: `Author <contact@email.local>`, + }}, + listUnknown: []*file{{ + path: `fileU1`, + licenseID: valExist, + idxLicenseID: -1, + copyrightYear: `2000`, + copyrightText: valExist, + idxCopyrightText: 2, + }}, + } + test.Assert(t, workDir, exp, got) +} diff --git a/testdata/loadReport/ok/spdxconv.report b/testdata/loadReport/ok/spdxconv.report new file mode 100644 index 0000000..ab58899 --- /dev/null +++ b/testdata/loadReport/ok/spdxconv.report @@ -0,0 +1,13 @@ + +// comment +//spdxconv:regular +fileR1,default,unknown,default +file R2,exist:1,2024,exist:-1 +//spdxconv:binary + +fileB1,BSD-3-Clause,2000-2026,Author <contact@email.local> + +// comment +//spdxconv:unknown +// comment +fileU1,exist:-1,2000,exist:2 |
