xref: /aosp_15_r20/external/spdx-tools/tvsaver/saver2v3/save_document.go (revision ba677afa8f67bb56cbc794f4d0e378e0da058e16)
1*ba677afaSXin Li// Package saver2v3 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 saver2v3
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_3"
14*ba677afaSXin Li)
15*ba677afaSXin Li
16*ba677afaSXin Li// RenderDocument2_3 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_3(doc *v2_3.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_3(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_3(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_3(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_3(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_3(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_3(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_3(rev, w)
100*ba677afaSXin Li		}
101*ba677afaSXin Li	}
102*ba677afaSXin Li
103*ba677afaSXin Li	return nil
104*ba677afaSXin Li}
105