Skip to content

Commit 85d779e

Browse files
authored
Merge pull request #293 from codacy/add-sarif-formatter
feature: Add sarif formatter
2 parents 7c6605d + 41b069f commit 85d779e

File tree

11 files changed

+428
-42
lines changed

11 files changed

+428
-42
lines changed

.circleci/config.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,18 +144,21 @@ workflows:
144144
write_sbt_version: true
145145
- codacy/sbt:
146146
name: compile
147+
install_sbt_version: 1.3.12
147148
cmd: sbt coverage +test:compile
148149
persist_to_workspace: true
149150
requires:
150151
- codacy/checkout_and_version
151152
- codacy/sbt:
152153
name: lint
154+
install_sbt_version: 1.3.12
153155
cmd: |
154156
sbt "scalafmtCheckAll;scalafmtSbtCheck;scapegoat;scalafixEnable;scalafix --test"
155157
requires:
156158
- compile
157159
- codacy/sbt:
158160
name: test
161+
install_sbt_version: 1.3.12
159162
cmd: |
160163
git config --global user.email "team@codacy.com"
161164
git config --global user.name "Codacy Team"
@@ -165,6 +168,7 @@ workflows:
165168
- compile
166169
- codacy/sbt:
167170
name: publish_docker_locally
171+
install_sbt_version: 1.3.12
168172
cmd: |
169173
sbt "set codacyAnalysisCli / version := \"dev-snapshot\";
170174
codacyAnalysisCli/docker:publishLocal"
@@ -186,6 +190,7 @@ workflows:
186190
- maven_dependencies
187191
- codacy/sbt:
188192
name: publish_lib
193+
install_sbt_version: 1.3.12
189194
context: CodacyAWS
190195
cmd: |
191196
sbt "retrieveGPGKeys;

.jvmopts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
-XX:+UnlockExperimentalVMOptions
2+
-XX:+UseCGroupMemoryLimitForHeap
3+
-XX:MaxRAMFraction=1
4+
-Xms1024M
5+
-Xss256M
6+
-Xmx3072M

cli/src/main/scala/com/codacy/analysis/cli/analysis/AnalyseExecutor.scala

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ import com.codacy.analysis.core.utils.InheritanceOps.InheritanceOps
1515
import com.codacy.analysis.core.utils.SeqOps._
1616
import com.codacy.analysis.core.utils.TryOps._
1717
import com.codacy.analysis.core.utils.{LanguagesHelper, SetOps}
18+
import com.codacy.plugins.api.PatternDescription
1819
import com.codacy.plugins.api.languages.Language
20+
import com.codacy.plugins.results.traits.DockerToolDocumentation
21+
import com.codacy.plugins.utils.impl.CacheDockerHelper
1922
import org.log4s.{Logger, getLogger}
2023
import play.api.libs.json.JsValue
2124

@@ -54,10 +57,18 @@ class AnalyseExecutor(formatter: Formatter,
5457

5558
tool match {
5659
case tool: Tool =>
60+
val toolDocumentation = ToolCollector
61+
.fromUuid(tool.uuid)
62+
.map(dockerTool => new DockerToolDocumentation(dockerTool, new CacheDockerHelper()))
5763
val toolHasConfigFiles = fileCollector.hasConfigurationFiles(tool, allFiles)
5864
val analysisResults =
5965
issues(tool, filteredFiles, configuration.toolConfiguration, toolHasConfigFiles)
60-
IssuesToolExecutorResult(tool.name, filteredFiles.readableFiles, analysisResults)
66+
IssuesToolExecutorResult(
67+
tool.name,
68+
toolDocumentation.flatMap(_.toolSpecification),
69+
toolDocumentation.flatMap(_.patternDescriptions).getOrElse(Set.empty[PatternDescription]),
70+
filteredFiles.readableFiles,
71+
analysisResults)
6172
case metricsTool: MetricsTool =>
6273
val analysisResults =
6374
analyser.metrics(metricsTool, filteredFiles.directory, Some(filteredFiles.readableFiles))
@@ -91,7 +102,13 @@ class AnalyseExecutor(formatter: Formatter,
91102
val executorResults = issuesResults ++ duplicationResults ++ processedFileMetrics
92103

93104
formatter.begin()
94-
executorResults.foreach(_.analysisResults.foreach(results => formatter.addAll(results.to[List])))
105+
executorResults.foreach {
106+
case toolResults: IssuesToolExecutorResult =>
107+
toolResults.analysisResults.foreach(results =>
108+
formatter.addAll(toolResults.toolSpecification, toolResults.patternDescriptions, results.to[List]))
109+
case toolResults =>
110+
toolResults.analysisResults.foreach(results => formatter.addAll(None, Set.empty, results.to[List]))
111+
}
95112
formatter.end()
96113

97114
executorResults
@@ -180,7 +197,12 @@ object AnalyseExecutor {
180197
def analysisResults: Try[Set[T]]
181198
}
182199

183-
final case class IssuesToolExecutorResult(toolName: String, files: Set[Path], analysisResults: Try[Set[ToolResult]])
200+
final case class IssuesToolExecutorResult(
201+
toolName: String,
202+
toolSpecification: Option[com.codacy.plugins.api.results.Tool.Specification],
203+
patternDescriptions: Set[PatternDescription],
204+
files: Set[Path],
205+
analysisResults: Try[Set[ToolResult]])
184206
extends ExecutorResult[ToolResult]
185207

186208
final case class MetricsToolExecutorResult(language: String, files: Set[Path], analysisResults: Try[Set[FileMetrics]])

cli/src/main/scala/com/codacy/analysis/cli/command/AnalyseCommand.scala

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,10 @@ object AnalyseCommand {
4040
val configuration: CLIConfiguration =
4141
CLIConfiguration(codacyClientOpt, environment, analyse, new CodacyConfigurationFileLoader)
4242
val formatter: Formatter =
43-
Formatter(configuration.analysis.output.format, configuration.analysis.output.file)
43+
Formatter(
44+
configuration.analysis.output.format,
45+
environment.baseProjectDirectory(analyse.directory),
46+
configuration.analysis.output.file)
4447
val fileCollector: FileCollector[Try] = FileCollector.defaultCollector()
4548
val analyseExecutor: AnalyseExecutor =
4649
new AnalyseExecutor(formatter, Analyser(analyse.extras.analyser), fileCollector, configuration.analysis)
@@ -200,9 +203,9 @@ class AnalyseCommand(analyse: Analyse,
200203

201204
private def issuesToUpload(toolAndIssuesResults: Seq[IssuesToolExecutorResult]): Seq[ResultsUploader.ToolResults] = {
202205
toolAndIssuesResults.map {
203-
case IssuesToolExecutorResult(toolName, files, Success(issues)) =>
206+
case IssuesToolExecutorResult(toolName, _, _, files, Success(issues)) =>
204207
ResultsUploader.ToolResults(toolName, files, Right(issues))
205-
case IssuesToolExecutorResult(toolName, files, Failure(error)) =>
208+
case IssuesToolExecutorResult(toolName, _, _, files, Failure(error)) =>
206209
ResultsUploader.ToolResults(toolName, files, Left(error.getMessage))
207210
}(collection.breakOut)
208211
}

cli/src/main/scala/com/codacy/analysis/cli/formatter/Formatter.scala

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ import java.io.{FileOutputStream, PrintStream}
44

55
import better.files.File
66
import com.codacy.analysis.core.model.Result
7+
import com.codacy.plugins.api.PatternDescription
78
import org.log4s.{Logger, getLogger}
89

910
trait FormatterCompanion {
1011
def name: String
11-
def apply(stream: PrintStream): Formatter
12+
def apply(outputStream: PrintStream, executionDirectory: File): Formatter
1213
}
1314

1415
trait Formatter {
@@ -17,9 +18,9 @@ trait Formatter {
1718

1819
def begin(): Unit
1920

20-
def add(element: Result): Unit
21-
22-
def addAll(elements: Seq[Result]): Unit = elements.foreach(add)
21+
def addAll(toolSpecification: Option[com.codacy.plugins.api.results.Tool.Specification],
22+
patternDescriptions: Set[PatternDescription],
23+
elements: Seq[Result]): Unit
2324

2425
def end(): Unit
2526

@@ -33,20 +34,21 @@ object Formatter {
3334

3435
val defaultFormatter: FormatterCompanion = Text
3536

36-
val allFormatters: Set[FormatterCompanion] = Set(defaultFormatter, Json)
37+
val allFormatters: Set[FormatterCompanion] = Set(defaultFormatter, Json, Sarif)
3738

38-
def apply(name: String,
39-
file: Option[File] = Option.empty,
39+
def apply(formatterName: String,
40+
executionDirectory: File,
41+
outputFile: Option[File] = Option.empty,
4042
printStream: Option[PrintStream] = Option.empty): Formatter = {
4143

42-
val builder = allFormatters.find(_.name.equalsIgnoreCase(name)).getOrElse {
43-
logger.warn(s"Could not find formatter for name $name. Using ${defaultFormatter.name} as fallback.")
44+
val builder = allFormatters.find(_.name.equalsIgnoreCase(formatterName)).getOrElse {
45+
logger.warn(s"Could not find formatter for name $formatterName. Using ${defaultFormatter.name} as fallback.")
4446
defaultFormatter
4547
}
4648

47-
val stream = file.map(asPrintStream).orElse(printStream).getOrElse(defaultPrintStream)
49+
val stream = outputFile.map(asPrintStream).orElse(printStream).getOrElse(defaultPrintStream)
4850

49-
builder(stream)
51+
builder(stream, executionDirectory)
5052
}
5153

5254
private def asPrintStream(file: File) = {

cli/src/main/scala/com/codacy/analysis/cli/formatter/Json.scala

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,18 @@ package com.codacy.analysis.cli.formatter
33
import java.io.PrintStream
44
import java.nio.file.Path
55

6+
import better.files.File
67
import com.codacy.analysis.core.model.Result
7-
import com.codacy.plugins.api.results
8+
import com.codacy.plugins.api.{PatternDescription, results}
89
import io.circe.Encoder
910
import io.circe.generic.auto._
1011
import io.circe.syntax._
1112

1213
import scala.util.Properties
1314

1415
object Json extends FormatterCompanion {
15-
val name: String = "json"
16-
def apply(stream: PrintStream): Formatter = new Json(stream)
16+
override val name: String = "json"
17+
override def apply(outputStream: PrintStream, executionDirectory: File): Formatter = new Json(outputStream)
1718
}
1819

1920
private[formatter] class Json(val stream: PrintStream) extends Formatter {
@@ -37,7 +38,11 @@ private[formatter] class Json(val stream: PrintStream) extends Formatter {
3738
stream.flush()
3839
}
3940

40-
def add(element: Result): Unit = {
41+
override def addAll(toolSpecification: Option[com.codacy.plugins.api.results.Tool.Specification],
42+
patternDescriptions: Set[PatternDescription],
43+
elements: Seq[Result]): Unit = elements.foreach(add)
44+
45+
private def add(element: Result): Unit = {
4146
if (alreadyPrinted) stream.print(",") else alreadyPrinted = true
4247
stream.print(element.asJson.noSpaces)
4348
}

0 commit comments

Comments
 (0)