Skip to content

Commit 943ea0d

Browse files
authored
Merge pull request #511 from codacy/add-custom-registry
feat: [TCE-1039] Add parameter 'registryAddress' in order to support alternative registry addresses
2 parents 097d39b + 0091e95 commit 943ea0d

File tree

9 files changed

+66
-37
lines changed

9 files changed

+66
-37
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ Found [Clone] 7 duplicated lines with 10 tokens:
215215
* `--skip-ssl-verification` [default: false] - Skip the SSL certificate verification when communicating with the Codacy API
216216
* `--parallel` [default: 2] - Number of tools to run in parallel
217217
* `--max-allowed-issues` [default: 0] - Maximum number of issues allowed for the analysis to succeed
218+
* `--registry-address` [default: empty] - Alternative registry address (e.g. artprod.mycompany/)
218219
* `--fail-if-incomplete` [default: false] - Fail the analysis if any tool fails to run
219220
* `--allow-network` [default: false] - Allow network access, so tools that need it can execute (e.g. findbugs)
220221
* `--force-file-permissions` [default: false] - Force files to be readable by changing the permissions before running the analysis

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,11 @@ class AnalyseExecutor(formatter: Formatter,
4242
filesGlobalTarget = fileCollector.filterGlobal(allFilesTarget, configuration.fileExclusionRules)
4343
languages =
4444
LanguagesHelper.fromFileTarget(filesGlobalTarget, configuration.fileExclusionRules.allowedExtensionsByLanguage)
45-
tools <- toolSelector.allTools(configuration.tool, configuration.toolConfiguration, languages)
45+
tools <- toolSelector.allTools(
46+
configuration.tool,
47+
configuration.toolConfiguration,
48+
languages,
49+
configuration.registryAddress)
4650
} yield (allFilesTarget, filesGlobalTarget, tools)
4751

4852
val analysisResult: Either[CLIError, Seq[ExecutorResult[_]]] = filesTargetAndTool.map {

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

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ class ToolSelector(toolRepository: ToolRepository) {
1515

1616
def allTools(toolInputOpt: Option[String],
1717
configuration: CLIConfiguration.Tool,
18-
languages: Set[Language]): Either[CLIError, Set[ITool]] = {
18+
languages: Set[Language],
19+
registryAddress: String): Either[CLIError, Set[ITool]] = {
1920

2021
def duplicationToolsEither: Either[CLIError.CouldNotGetTools, Set[DuplicationTool]] =
2122
duplicationToolCollector.fromLanguages(languages).left.map(e => CLIError.CouldNotGetTools(e.message))
@@ -26,7 +27,7 @@ class ToolSelector(toolRepository: ToolRepository) {
2627
toolInputOpt match {
2728
case None =>
2829
for {
29-
tools <- tools(configuration, languages)
30+
tools <- tools(configuration, languages, registryAddress)
3031
duplicationTools <- duplicationToolsEither
3132
metricsTools <- metricsToolsEither
3233
} yield tools ++ metricsTools ++ duplicationTools
@@ -38,28 +39,30 @@ class ToolSelector(toolRepository: ToolRepository) {
3839
duplicationToolsEither.map(_.map(_.to[ITool]))
3940

4041
case Some("issues") =>
41-
val toolsEither = tools(configuration, languages)
42+
val toolsEither = tools(configuration, languages, registryAddress)
4243
toolsEither.map(_.map(_.to[ITool]))
4344

4445
case Some(toolInput) =>
45-
val toolEither = tool(toolInput, languages)
46+
val toolEither = tool(toolInput, languages, registryAddress)
4647
toolEither.map(_.map(_.to[ITool]))
4748
}
4849
}
4950

50-
def tools(configuration: CLIConfiguration.Tool, languages: Set[Language]): Either[CLIError, Set[Tool]] = {
51+
def tools(configuration: CLIConfiguration.Tool,
52+
languages: Set[Language],
53+
registryAddress: String): Either[CLIError, Set[Tool]] = {
5154
def fromRemoteConfig: Either[CLIError, Set[Tool]] = {
5255
configuration.toolConfigurations.left.map(CLIError.NoRemoteProjectConfiguration).flatMap { toolConfiguration =>
5356
val toolUuids = toolConfiguration.filter(_.enabled).map(_.uuid)
5457
toolCollector
55-
.fromToolUUIDs(toolUuids, languages)
58+
.fromToolUUIDs(toolUuids, languages, registryAddress)
5659
.left
5760
.map(_ => CLIError.NonExistentToolsFromRemoteConfiguration(toolUuids))
5861
}
5962
}
6063

6164
def fromLocalConfig: Either[CLIError, Set[Tool]] = {
62-
toolCollector.fromLanguages(languages).left.map(CLIError.from)
65+
toolCollector.fromLanguages(languages, registryAddress).left.map(CLIError.from)
6366
}
6467

6568
for {
@@ -68,8 +71,8 @@ class ToolSelector(toolRepository: ToolRepository) {
6871
} yield CLIError.CouldNotGetTools(s"${e1.message} and ${e2.message}")
6972
}
7073

71-
def tool(toolInput: String, languages: Set[Language]): Either[CLIError, Set[Tool]] = {
72-
toolCollector.fromNameOrUUID(toolInput, languages).left.map(CLIError.from)
74+
def tool(toolInput: String, languages: Set[Language], registryAddress: String): Either[CLIError, Set[Tool]] = {
75+
toolCollector.fromNameOrUUID(toolInput, languages, registryAddress).left.map(CLIError.from)
7376
}
7477

7578
def fromUuid(uuid: String): Either[AnalyserError, FullToolSpec] = {

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,8 @@ final case class Analyze(
157157
maxAllowedIssues: Int = 0,
158158
@ValueDescription("Fail the analysis if any tool fails to run")
159159
failIfIncomplete: Int @@ Counter = Tag.of(0),
160+
@ExtraName("r") @ValueDescription("[default: empty] - Alternative registry address (e.g. artprod.mycompany/)")
161+
registryAddress: String = "",
160162
@ValueDescription("Force files to be readable by changing the permissions before running the analysis")
161163
forceFilePermissions: Int @@ Counter = Tag.of(0),
162164
@ValueDescription("Maximum time each tool has to execute")

cli/src/main/scala/com/codacy/analysis/cli/configuration/CLIConfiguration.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ object CLIConfiguration {
3737
fileExclusionRules: CLIConfiguration.FileExclusionRules,
3838
toolConfiguration: CLIConfiguration.Tool,
3939
tmpDirectory: Option[File] = None,
40-
maxToolMemory: Option[String] = None)
40+
maxToolMemory: Option[String] = None,
41+
registryAddress: String = "")
4142

4243
object Analysis {
4344

@@ -62,7 +63,8 @@ object CLIConfiguration {
6263
fileExclusionRules,
6364
toolConfiguration,
6465
tmpDirectory,
65-
maxToolMemory)
66+
maxToolMemory,
67+
analyze.registryAddress)
6668
}
6769
}
6870

cli/src/test/scala/com/codacy/analysis/cli/ToolSelectorSpec.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ class ToolSelectorSpec extends Specification with NoLanguageFeatures {
6060

6161
val toolConfiguration =
6262
CLIConfiguration.Tool(Option.empty, allowNetwork = false, Left("no config"), Option.empty, Map.empty)
63-
val rubyTools = toolSelector.allTools(None, toolConfiguration, Set(Languages.Ruby))
63+
val rubyTools = toolSelector.allTools(None, toolConfiguration, Set(Languages.Ruby), "")
6464

6565
rubyTools should beRight
6666
rubyTools must beLike {
@@ -79,7 +79,7 @@ class ToolSelectorSpec extends Specification with NoLanguageFeatures {
7979

8080
val languages = LanguagesHelper.fromFileTarget(emptyFilesTarget, Map.empty)
8181

82-
val toolEither = toolSelector.tool(expectedToolName, languages)
82+
val toolEither = toolSelector.tool(expectedToolName, languages, "")
8383
toolEither must beLeft(CLIError.NonExistingToolInput(expectedToolName))
8484
}
8585

@@ -97,7 +97,7 @@ class ToolSelectorSpec extends Specification with NoLanguageFeatures {
9797
val toolConfiguration =
9898
CLIConfiguration.Tool(Option.empty, allowNetwork = false, Right(toolConfigs), Option.empty, Map.empty)
9999

100-
val toolEither = toolSelector.tools(toolConfiguration, Set(Javascript, Python))
100+
val toolEither = toolSelector.tools(toolConfiguration, Set(Javascript, Python), "")
101101
toolEither must beRight
102102
toolEither must beLike {
103103
case Right(toolSet) =>
@@ -113,7 +113,7 @@ class ToolSelectorSpec extends Specification with NoLanguageFeatures {
113113
CLIConfiguration.Tool(Option.empty, allowNetwork = false, toolConfigs, Option.empty, Map.empty)
114114
val languages = LanguagesHelper.fromFileTarget(filesTarget, Map.empty)
115115

116-
val toolEither = toolSelector.tools(toolConfiguration, languages)
116+
val toolEither = toolSelector.tools(toolConfiguration, languages, "")
117117
toolEither must beRight
118118
toolEither must beLike {
119119
case Right(toolSet) =>
@@ -129,7 +129,7 @@ class ToolSelectorSpec extends Specification with NoLanguageFeatures {
129129
CLIConfiguration.Tool(Option.empty, allowNetwork = true, toolConfigs, Option.empty, languageExtensions)
130130
val languages = LanguagesHelper.fromFileTarget(filesTarget, languageExtensions)
131131

132-
val toolEither = toolSelector.tools(toolConfiguration, languages)
132+
val toolEither = toolSelector.tools(toolConfiguration, languages, "")
133133
toolEither must beRight
134134
toolEither must beLike {
135135
case Right(toolSet) =>

cli/src/test/scala/com/codacy/analysis/cli/configuration/CLIConfigurationSpec.scala

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,8 @@ class CLIConfigurationSpec extends Specification with NoLanguageFeatures {
105105
toolConfigurations = Left("no remote config"),
106106
extraToolConfigurations = Option.empty,
107107
extensionsByLanguage = Map.empty),
108-
maxToolMemory = Some("3000000000")),
108+
maxToolMemory = Some("3000000000"),
109+
registryAddress = ""),
109110
upload = CLIConfiguration.Upload(commitUuid = commitUuid, upload = true, batchSize = batchSize),
110111
result = CLIConfiguration.Result(maxAllowedIssues = 5, failIfIncomplete = true))
111112

@@ -168,7 +169,8 @@ class CLIConfigurationSpec extends Specification with NoLanguageFeatures {
168169
CLIConfiguration.IssuesTool.Parameter(name = parameter.name, value = parameter.value))))))),
169170
extraToolConfigurations = Option.empty,
170171
extensionsByLanguage = Map.empty),
171-
maxToolMemory = Some("3000000000")),
172+
maxToolMemory = Some("3000000000"),
173+
registryAddress = ""),
172174
upload = CLIConfiguration.Upload(commitUuid = commitUuid, upload = false, batchSize = batchSize),
173175
result = CLIConfiguration.Result(maxAllowedIssues = 0, failIfIncomplete = false))
174176

@@ -220,7 +222,8 @@ class CLIConfigurationSpec extends Specification with NoLanguageFeatures {
220222
Map("engine no. 9" -> CLIConfiguration.IssuesTool
221223
.Extra(baseSubDir = engineConfig.baseSubDir, extraValues = engineConfig.extraValues))),
222224
extensionsByLanguage = Map(Languages.Scala -> Set(".scala", ".alacs"))),
223-
maxToolMemory = Some("3000000000")),
225+
maxToolMemory = Some("3000000000"),
226+
registryAddress = ""),
224227
upload = CLIConfiguration.Upload(commitUuid = commitUuid, upload = false, batchSize = batchSize),
225228
result = CLIConfiguration.Result(maxAllowedIssues = 0, failIfIncomplete = false))
226229

@@ -253,7 +256,8 @@ class CLIConfigurationSpec extends Specification with NoLanguageFeatures {
253256
toolConfigurations = Left("no remote config"),
254257
extraToolConfigurations = Option.empty,
255258
extensionsByLanguage = Map.empty),
256-
maxToolMemory = Some("3000000000")),
259+
maxToolMemory = Some("3000000000"),
260+
registryAddress = ""),
257261
upload = CLIConfiguration.Upload(commitUuid = commitUuid, upload = false, batchSize = batchSize),
258262
result = CLIConfiguration.Result(maxAllowedIssues = 0, failIfIncomplete = false))
259263

@@ -333,7 +337,8 @@ class CLIConfigurationSpec extends Specification with NoLanguageFeatures {
333337
Map("engine no. 9" -> CLIConfiguration.IssuesTool
334338
.Extra(baseSubDir = engineConfig.baseSubDir, extraValues = engineConfig.extraValues))),
335339
extensionsByLanguage = Map(Languages.Scala -> Set(".sc"))),
336-
maxToolMemory = Some("3000000000")),
340+
maxToolMemory = Some("3000000000"),
341+
registryAddress = ""),
337342
upload = CLIConfiguration.Upload(commitUuid = commitUuid, upload = false, batchSize = batchSize),
338343
result = CLIConfiguration.Result(maxAllowedIssues = 0, failIfIncomplete = false))
339344

core/src/main/scala/com/codacy/analysis/core/tools/Tool.scala

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,11 @@ final case class SubDirectory(sourceDirectory: String, protected val subDirector
3838
filename.stripPrefix(subDirectory).stripPrefix(java.io.File.separator)
3939
}
4040

41-
class Tool(fullToolSpec: FullToolSpec, val languageToRun: Language, defaultRunTimeout: Duration) extends ITool {
41+
class Tool(fullToolSpec: FullToolSpec,
42+
val languageToRun: Language,
43+
defaultRunTimeout: Duration,
44+
registryAddress: String)
45+
extends ITool {
4246

4347
private val tool = fullToolSpec.tool
4448

@@ -72,7 +76,7 @@ class Tool(fullToolSpec: FullToolSpec, val languageToRun: Language, defaultRunTi
7276
}
7377

7478
val dockerInformation = new DockerInformation(
75-
dockerImage = fullToolSpec.tool.dockerImage,
79+
dockerImage = registryAddress + fullToolSpec.tool.dockerImage,
7680
needsCompilation = fullToolSpec.tool.needsCompilation)
7781

7882
val dockerRunner =
@@ -138,8 +142,8 @@ class Tool(fullToolSpec: FullToolSpec, val languageToRun: Language, defaultRunTi
138142

139143
object Tool {
140144

141-
def apply(fullToolSpec: FullToolSpec, languageToRun: Language): Tool = {
142-
new Tool(fullToolSpec, languageToRun, DockerRunner.defaultRunTimeout)
145+
def apply(fullToolSpec: FullToolSpec, languageToRun: Language, registryAddress: String): Tool = {
146+
new Tool(fullToolSpec, languageToRun, DockerRunner.defaultRunTimeout, registryAddress)
143147
}
144148
}
145149

@@ -156,18 +160,22 @@ class ToolCollector(toolRepository: ToolRepository) {
156160
}
157161
}
158162

159-
def fromNameOrUUID(toolInput: String, languages: Set[Language]): Either[AnalyserError, Set[Tool]] = {
160-
toolRepository.getTool(toolInput).flatMap(from(_, languages))
163+
def fromNameOrUUID(toolInput: String,
164+
languages: Set[Language],
165+
registryAddress: String): Either[AnalyserError, Set[Tool]] = {
166+
toolRepository.getTool(toolInput).flatMap(from(_, languages, registryAddress))
161167
}
162168

163-
def fromToolUUIDs(toolUuids: Set[String], languages: Set[Language]): Either[AnalyserError, Set[Tool]] = {
169+
def fromToolUUIDs(toolUuids: Set[String],
170+
languages: Set[Language],
171+
registryAddress: String): Either[AnalyserError, Set[Tool]] = {
164172
if (toolUuids.isEmpty) {
165173
Left(AnalyserError.NoActiveToolInConfiguration)
166174
} else {
167175
toolRepository.listSupportedTools().map { tools =>
168176
val toolsIdentified: Set[Tool] = tools.map { tool =>
169177
if (toolUuids.contains(tool.uuid)) {
170-
from(tool, languages) match {
178+
from(tool, languages, registryAddress) match {
171179
case Left(error) =>
172180
logger.warn(s"Failed to get tool for ${tool.name}.\nReason: ${error.message}")
173181
Set.empty
@@ -186,26 +194,30 @@ class ToolCollector(toolRepository: ToolRepository) {
186194
}
187195
}
188196

189-
private def from(tool: ToolSpec, languages: Set[Language]): Either[AnalyserError, Set[Tool]] = {
197+
private def from(tool: ToolSpec,
198+
languages: Set[Language],
199+
registryAddress: String): Either[AnalyserError, Set[Tool]] = {
190200
toolRepository.listPatterns(tool).map { patterns =>
191-
tool.languages.intersect(languages).map(language => Tool(FullToolSpec(tool, patterns), language))
201+
tool.languages.intersect(languages).map(language => Tool(FullToolSpec(tool, patterns), language, registryAddress))
192202
}
193203
}
194204

195-
private def toTool(tool: ToolSpec, languages: Set[Language]): Either[AnalyserError, List[Tool]] = {
205+
private def toTool(tool: ToolSpec,
206+
languages: Set[Language],
207+
registryAddress: String): Either[AnalyserError, List[Tool]] = {
196208
toolRepository.listPatterns(tool).map { patterns =>
197209
tool.languages
198210
.intersect(languages)
199211
.map { language =>
200-
Tool(FullToolSpec(tool, patterns), language)
212+
Tool(FullToolSpec(tool, patterns), language, registryAddress)
201213
}(collection.breakOut)
202214
}
203215
}
204216

205-
def fromLanguages(languages: Set[Language]): Either[AnalyserError, Set[Tool]] = {
217+
def fromLanguages(languages: Set[Language], registryAddress: String): Either[AnalyserError, Set[Tool]] = {
206218
for {
207219
tools <- toolRepository.listSupportedTools()
208-
toolsInfo <- tools.toList.flatTraverse(toolSpec => toTool(toolSpec, languages))
220+
toolsInfo <- tools.toList.flatTraverse(toolSpec => toTool(toolSpec, languages, registryAddress))
209221
_ <- if (toolsInfo.nonEmpty) Right(()) else Left(AnalyserError.NoToolsFoundForFiles)
210222
} yield {
211223
toolsInfo.toSet

core/src/test/scala/com.codacy.analysis.core/files/FileCollectorSpec.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ abstract class FileCollectorSpec(fileCollector: FileCollector[Try]) extends Spec
343343
val expectedConfigFiles = List("src/main/resources/docs/directory-tests/rails3/config/brakeman.yml")
344344

345345
val toolCollector = new ToolCollector(ToolRepositoryMock)
346-
def getTool(name: String, language: Language) = toolCollector.fromNameOrUUID(name, Set(language)).right.get.head
346+
def getTool(name: String, language: Language) = toolCollector.fromNameOrUUID(name, Set(language), "").right.get.head
347347

348348
fileCollector.getClass.getName should {
349349
"list files and filter files per tool" in {

0 commit comments

Comments
 (0)