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