1*ba677afaSXin Li// Package saver2v2 contains functions to render and write a tag-value 2*ba677afaSXin Li// formatted version of an in-memory SPDX document and its sections 3*ba677afaSXin Li// (version 2.2). 4*ba677afaSXin Li// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 5*ba677afaSXin Lipackage saver2v2 6*ba677afaSXin Li 7*ba677afaSXin Liimport ( 8*ba677afaSXin Li "fmt" 9*ba677afaSXin Li "io" 10*ba677afaSXin Li "sort" 11*ba677afaSXin Li 12*ba677afaSXin Li "github.com/spdx/tools-golang/spdx/common" 13*ba677afaSXin Li "github.com/spdx/tools-golang/spdx/v2_2" 14*ba677afaSXin Li) 15*ba677afaSXin Li 16*ba677afaSXin Li// RenderDocument2_2 is the main entry point to take an SPDX in-memory 17*ba677afaSXin Li// Document (version 2.2), and render it to the received io.Writer. 18*ba677afaSXin Li// It is only exported in order to be available to the tvsaver package, 19*ba677afaSXin Li// and typically does not need to be called by client code. 20*ba677afaSXin Lifunc RenderDocument2_2(doc *v2_2.Document, w io.Writer) error { 21*ba677afaSXin Li if doc.CreationInfo == nil { 22*ba677afaSXin Li return fmt.Errorf("Document had nil CreationInfo section") 23*ba677afaSXin Li } 24*ba677afaSXin Li 25*ba677afaSXin Li if doc.SPDXVersion != "" { 26*ba677afaSXin Li fmt.Fprintf(w, "SPDXVersion: %s\n", doc.SPDXVersion) 27*ba677afaSXin Li } 28*ba677afaSXin Li if doc.DataLicense != "" { 29*ba677afaSXin Li fmt.Fprintf(w, "DataLicense: %s\n", doc.DataLicense) 30*ba677afaSXin Li } 31*ba677afaSXin Li if doc.SPDXIdentifier != "" { 32*ba677afaSXin Li fmt.Fprintf(w, "SPDXID: %s\n", common.RenderElementID(doc.SPDXIdentifier)) 33*ba677afaSXin Li } 34*ba677afaSXin Li if doc.DocumentName != "" { 35*ba677afaSXin Li fmt.Fprintf(w, "DocumentName: %s\n", doc.DocumentName) 36*ba677afaSXin Li } 37*ba677afaSXin Li if doc.DocumentNamespace != "" { 38*ba677afaSXin Li fmt.Fprintf(w, "DocumentNamespace: %s\n", doc.DocumentNamespace) 39*ba677afaSXin Li } 40*ba677afaSXin Li // print EDRs in order sorted by identifier 41*ba677afaSXin Li sort.Slice(doc.ExternalDocumentReferences, func(i, j int) bool { 42*ba677afaSXin Li return doc.ExternalDocumentReferences[i].DocumentRefID < doc.ExternalDocumentReferences[j].DocumentRefID 43*ba677afaSXin Li }) 44*ba677afaSXin Li for _, edr := range doc.ExternalDocumentReferences { 45*ba677afaSXin Li fmt.Fprintf(w, "ExternalDocumentRef: DocumentRef-%s %s %s:%s\n", 46*ba677afaSXin Li edr.DocumentRefID, edr.URI, edr.Checksum.Algorithm, edr.Checksum.Value) 47*ba677afaSXin Li } 48*ba677afaSXin Li if doc.DocumentComment != "" { 49*ba677afaSXin Li fmt.Fprintf(w, "DocumentComment: %s\n", textify(doc.DocumentComment)) 50*ba677afaSXin Li } 51*ba677afaSXin Li 52*ba677afaSXin Li renderCreationInfo2_2(doc.CreationInfo, w) 53*ba677afaSXin Li 54*ba677afaSXin Li if len(doc.Files) > 0 { 55*ba677afaSXin Li fmt.Fprintf(w, "##### Unpackaged files\n\n") 56*ba677afaSXin Li sort.Slice(doc.Files, func(i, j int) bool { 57*ba677afaSXin Li return doc.Files[i].FileSPDXIdentifier < doc.Files[j].FileSPDXIdentifier 58*ba677afaSXin Li }) 59*ba677afaSXin Li for _, fi := range doc.Files { 60*ba677afaSXin Li renderFile2_2(fi, w) 61*ba677afaSXin Li } 62*ba677afaSXin Li } 63*ba677afaSXin Li 64*ba677afaSXin Li // sort Packages by identifier 65*ba677afaSXin Li sort.Slice(doc.Packages, func(i, j int) bool { 66*ba677afaSXin Li return doc.Packages[i].PackageSPDXIdentifier < doc.Packages[j].PackageSPDXIdentifier 67*ba677afaSXin Li }) 68*ba677afaSXin Li for _, pkg := range doc.Packages { 69*ba677afaSXin Li fmt.Fprintf(w, "##### Package: %s\n\n", pkg.PackageName) 70*ba677afaSXin Li renderPackage2_2(pkg, w) 71*ba677afaSXin Li } 72*ba677afaSXin Li 73*ba677afaSXin Li if len(doc.OtherLicenses) > 0 { 74*ba677afaSXin Li fmt.Fprintf(w, "##### Other Licenses\n\n") 75*ba677afaSXin Li for _, ol := range doc.OtherLicenses { 76*ba677afaSXin Li renderOtherLicense2_2(ol, w) 77*ba677afaSXin Li } 78*ba677afaSXin Li } 79*ba677afaSXin Li 80*ba677afaSXin Li if len(doc.Relationships) > 0 { 81*ba677afaSXin Li fmt.Fprintf(w, "##### Relationships\n\n") 82*ba677afaSXin Li for _, rln := range doc.Relationships { 83*ba677afaSXin Li renderRelationship2_2(rln, w) 84*ba677afaSXin Li } 85*ba677afaSXin Li fmt.Fprintf(w, "\n") 86*ba677afaSXin Li } 87*ba677afaSXin Li 88*ba677afaSXin Li if len(doc.Annotations) > 0 { 89*ba677afaSXin Li fmt.Fprintf(w, "##### Annotations\n\n") 90*ba677afaSXin Li for _, ann := range doc.Annotations { 91*ba677afaSXin Li renderAnnotation2_2(ann, w) 92*ba677afaSXin Li fmt.Fprintf(w, "\n") 93*ba677afaSXin Li } 94*ba677afaSXin Li } 95*ba677afaSXin Li 96*ba677afaSXin Li if len(doc.Reviews) > 0 { 97*ba677afaSXin Li fmt.Fprintf(w, "##### Reviews\n\n") 98*ba677afaSXin Li for _, rev := range doc.Reviews { 99*ba677afaSXin Li renderReview2_2(rev, w) 100*ba677afaSXin Li } 101*ba677afaSXin Li } 102*ba677afaSXin Li 103*ba677afaSXin Li return nil 104*ba677afaSXin Li} 105