Skip to content

Commit 998309b

Browse files
committed
feat(scanoss): Add snippet report generation
Implement functionality to generate snippet findings reports from SCANOSS scan results. Signed-off-by: Agustin Isasmendi <[email protected]>
1 parent 77293c6 commit 998309b

File tree

7 files changed

+246
-1
lines changed

7 files changed

+246
-1
lines changed

buildSrc/src/main/kotlin/LicenseUtils.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ object CopyrightableFiles {
3434
"plugins/reporters/asciidoc/src/main/resources/pdf-theme/pdf-theme.yml",
3535
"plugins/reporters/asciidoc/src/main/resources/templates/freemarker_implicit.ftl",
3636
"plugins/reporters/fossid/src/main/resources/templates/freemarker_implicit.ftl",
37+
"plugins/reporters/scanoss/src/main/resources/templates/freemarker_implicit.ftl",
3738
"plugins/reporters/freemarker/src/main/resources/templates/freemarker_implicit.ftl",
3839
"plugins/reporters/static-html/src/main/resources/prismjs/",
3940
"plugins/reporters/web-app-template/yarn.lock",

integrations/completions/ort-completion.fish

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ complete -c ort -f -n __fish_use_subcommand -a report -d 'Present Analyzer, Scan
149149
## Options for report
150150
complete -c ort -n "__fish_seen_subcommand_from report" -l ort-file -s i -r -F -d 'The ORT result file to use.'
151151
complete -c ort -n "__fish_seen_subcommand_from report" -l output-dir -s o -r -F -d 'The output directory to store the generated reports in.'
152-
complete -c ort -n "__fish_seen_subcommand_from report" -l report-formats -s f -r -d 'A comma-separated list of report formats to generate, any of [AOSD2.0, AOSD2.1, CtrlXAutomation, CycloneDX, DocBookTemplate, EvaluatedModel, FossID, FossIdSnippet, HtmlTemplate, ManPageTemplate, Opossum, PdfTemplate, PlainTextTemplate, SpdxDocument, StaticHTML, TrustSource, WebApp].'
152+
complete -c ort -n "__fish_seen_subcommand_from report" -l report-formats -s f -r -d 'A comma-separated list of report formats to generate, any of [AOSD2.0, AOSD2.1, CtrlXAutomation, CycloneDX, DocBookTemplate, EvaluatedModel, FossID, FossIdSnippet, HtmlTemplate, ManPageTemplate, Opossum, PdfTemplate, PlainTextTemplate, ScanossSnippet, SpdxDocument, StaticHTML, TrustSource, WebApp].'
153153
complete -c ort -n "__fish_seen_subcommand_from report" -l copyright-garbage-file -r -F -d 'A file containing copyright statements which are marked as garbage. This can make the output inconsistent with the evaluator output but is useful when testing copyright garbage.'
154154
complete -c ort -n "__fish_seen_subcommand_from report" -l custom-license-texts-dir -r -F -d 'A directory which maps custom license IDs to license texts. It should contain one text file per license with the license ID as the filename. A custom license text is used only if its ID has a \'LicenseRef-\' prefix and if the respective license text is not known by ORT.'
155155
complete -c ort -n "__fish_seen_subcommand_from report" -l how-to-fix-text-provider-script -r -F -d 'The path to a Kotlin script which returns an instance of a \'HowToFixTextProvider\'. That provider injects how-to-fix texts in Markdown format for ORT issues.'
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright (C) 2025 The ORT Project Authors (see <https://github.com/oss-review-toolkit/ort/blob/main/NOTICE>)
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* SPDX-License-Identifier: Apache-2.0
17+
* License-Filename: LICENSE
18+
*/
19+
20+
plugins {
21+
// Apply precompiled plugins.
22+
id("ort-plugin-conventions")
23+
}
24+
25+
dependencies {
26+
api(projects.reporter)
27+
28+
ksp(projects.reporter)
29+
30+
implementation(projects.model)
31+
implementation(projects.plugins.reporters.asciidocReporter)
32+
implementation(projects.plugins.reporters.freemarkerReporter)
33+
implementation(projects.utils.commonUtils)
34+
implementation(projects.utils.ortUtils)
35+
36+
implementation(libs.kotlinx.coroutines)
37+
38+
testImplementation(libs.mockk)
39+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright (C) 2025 The ORT Project Authors (see <https://github.com/oss-review-toolkit/ort/blob/main/NOTICE>)
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* SPDX-License-Identifier: Apache-2.0
17+
* License-Filename: LICENSE
18+
*/
19+
20+
package org.ossreviewtoolkit.plugins.reporters.scanoss
21+
22+
import java.io.File
23+
24+
import org.ossreviewtoolkit.plugins.api.OrtPlugin
25+
import org.ossreviewtoolkit.plugins.api.PluginDescriptor
26+
import org.ossreviewtoolkit.plugins.reporters.asciidoc.AsciiDocTemplateReporterConfig
27+
import org.ossreviewtoolkit.plugins.reporters.asciidoc.HtmlTemplateReporter
28+
import org.ossreviewtoolkit.reporter.Reporter
29+
import org.ossreviewtoolkit.reporter.ReporterFactory
30+
import org.ossreviewtoolkit.reporter.ReporterInput
31+
32+
@OrtPlugin(
33+
displayName = "SCANOSS Snippet Reporter",
34+
description = "Generates a detailed report of the SCANOSS snippet findings.",
35+
factory = ReporterFactory::class
36+
)
37+
class ScanossSnippetReporter(override val descriptor: PluginDescriptor = ScanossSnippetReporterFactory.descriptor) :
38+
Reporter by delegateReporter {
39+
companion object {
40+
private val delegateReporter = HtmlTemplateReporter(
41+
ScanossSnippetReporterFactory.descriptor,
42+
AsciiDocTemplateReporterConfig(templateIds = listOf("scanoss_snippet"), templatePaths = null)
43+
)
44+
}
45+
46+
override fun generateReport(input: ReporterInput, outputDir: File): List<Result<File>> {
47+
val hasScanossResults = input.ortResult.scanner?.scanResults?.any { it.scanner.name == "SCANOSS" } == true
48+
require(hasScanossResults) { "No SCANOSS scan results have been found." }
49+
50+
return delegateReporter.generateReport(input, outputDir)
51+
}
52+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Use Unix line endings for Freemarker templates for consistency across platforms.
2+
**/*.ftl text eol=lf
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
[#--
2+
Copyright (C) 2025 The ORT Project Authors (see <https://github.com/oss-review-toolkit/ort/blob/main/NOTICE>)
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
https://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
16+
SPDX-License-Identifier: Apache-2.0
17+
License-Filename: LICENSE
18+
--]
19+
20+
:publisher: OSS Review Toolkit
21+
[#assign now = .now]
22+
:revdate: ${now?date?iso_local}
23+
24+
:title-page:
25+
:sectnums:
26+
:toc:
27+
28+
= SCANOSS Snippets
29+
List of all the provenances with their files and snippets.
30+
[#list ortResult.scanner.scanResults as scanResult]
31+
32+
[#assign snippetsLimitIssue = helper.getSnippetsLimitIssue()]
33+
34+
[#if snippetsLimitIssue?has_content]
35+
[WARNING]
36+
====
37+
${snippetsLimitIssue}
38+
====
39+
[/#if]
40+
41+
[#if scanResult.provenance.vcsInfo??]
42+
[#assign url = scanResult.provenance.vcsInfo.url]
43+
[#else]
44+
[#assign url = scanResult.provenance.sourceArtifact.url]
45+
[/#if]
46+
== Provenance '${url}'
47+
48+
[#assign summary = scanResult.summary]
49+
50+
Scan start time : ${summary.startTime} +
51+
End time : ${summary.startTime} +
52+
[#if scanResult.provenance.vcsInfo??]
53+
[#assign gitRepoUrl = url]
54+
[#assign gitRevision = scanResult.provenance.vcsInfo.revision]
55+
Git repo URL: ${gitRepoUrl} +
56+
Git revision: ${gitRevision}
57+
58+
[#if gitRepoUrl?contains("github.com")]
59+
[#assign githubBaseURL = '${gitRepoUrl?remove_ending(".git")}/blob/${gitRevision}']
60+
[/#if]
61+
[/#if]
62+
63+
[#list helper.groupSnippetsByFile(summary.snippetFindings) as filePath, snippetFindings ]
64+
65+
[#if gitRepoUrl?? && gitRepoUrl?contains("github.com")]
66+
[#assign localFileURL = '${githubBaseURL}/${filePath}[${filePath}]']
67+
[#else]
68+
[#assign localFileURL = "${filePath}"]
69+
[/#if]
70+
[#assign licenses = helper.collectLicenses(snippetFindings)]
71+
72+
*${localFileURL}* +
73+
License(s):
74+
[#list licenses as license]
75+
${license}[#sep],
76+
[/#list]
77+
78+
[#list helper.groupSnippetsBySourceLines(snippetFindings) as sourceLocation, snippetFinding]
79+
[#assign snippetCount = snippetFinding.snippets?size]
80+
81+
[width=100%]
82+
[cols="1,3,4,1"]
83+
|===
84+
| Source Location | pURL | License | Score
85+
86+
.${snippetCount*2}+|
87+
Partial match +
88+
${sourceLocation.startLine?c}-${sourceLocation.endLine?c}
89+
90+
91+
[#list snippetFinding.snippets as snippet ]
92+
93+
| ${snippet.purl!""}
94+
| ${snippet.license!""}
95+
| ${snippet.score!""}
96+
97+
4+a|
98+
.Create a snippet choice for this snippet or mark it as false positive
99+
[%collapsible]
100+
====
101+
Add the following lines to the *.ort.yml* file.
102+
103+
To **choose** this snippet:
104+
[source,yaml]
105+
--
106+
snippet_choices:
107+
- provenance:
108+
url: "${scanResult.provenance.vcsInfo.url}"
109+
choices:
110+
- given:
111+
source_location:
112+
path: "${filePath}"
113+
start_line: ${snippetFinding.sourceLocation.startLine?c}
114+
end_line: ${snippetFinding.sourceLocation.endLine?c}
115+
choice:
116+
purl: "${snippet.purl!""}"
117+
reason: "ORIGINAL_FINDING"
118+
comment: "Explain why this snippet choice was made"
119+
--
120+
Or to mark this location has having ONLY **false positives snippets**:
121+
[source,yaml]
122+
--
123+
snippet_choices:
124+
- provenance:
125+
url: "${scanResult.provenance.vcsInfo.url}"
126+
choices:
127+
- given:
128+
source_location:
129+
path: "${filePath}"
130+
start_line: ${snippetFinding.sourceLocation.startLine?c}
131+
end_line: ${snippetFinding.sourceLocation.endLine?c}
132+
choice:
133+
reason: "NO_RELEVANT_FINDING"
134+
comment: "Explain why this location has only false positives snippets"
135+
--
136+
====
137+
[/#list]
138+
|===
139+
[/#list]
140+
[/#list]
141+
[/#list]
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[#ftl]
2+
[#-- @implicitly included --]
3+
4+
[#-- @ftlvariable name="projects" type="kotlin.collections.Set<org.ossreviewtoolkit.reporter.utils.FreemarkerTemplateProcessor.PackageModel>" --]
5+
[#-- @ftlvariable name="packages" type="kotlin.collections.Set<org.ossreviewtoolkit.reporter.utils.FreemarkerTemplateProcessor.PackageModel>" --]
6+
[#-- @ftlvariable name="ortResult" type="org.ossreviewtoolkit.model.OrtResult" --]
7+
[#-- @ftlvariable name="licenseTextProvider" type="org.ossreviewtoolkit.reporter.LicenseTextProvider" --]
8+
[#-- @ftlvariable name="LicenseView" type="org.ossreviewtoolkit.model.licenses.LicenseView" --]
9+
[#-- @ftlvariable name="helper" type="org.ossreviewtoolkit.plugins.reporters.freemarker.FreemarkerTemplateProcessor.TemplateHelper" --]
10+
[#-- @ftlvariable name="projectsAsPackages" type="kotlin.collections.Set<org.ossreviewtoolkit.model.Identifier>" --]

0 commit comments

Comments
 (0)