11package codacy .pylint
22
3+ import java .io .File
34import java .nio .file .{Files , Path }
45
5- import codacy .dockerApi ._
6- import codacy .dockerApi .utils .{CommandRunner , FileHelper , ToolHelper }
6+ import codacy .docker .api ._
7+ import codacy .docker .api .utils .ToolHelper
8+ import codacy .dockerApi .utils .{CommandRunner , FileHelper }
79import play .api .libs .json ._
810
911import scala .sys .process ._
1012import scala .util .{Properties , Success , Try }
1113
1214object Pylint extends Tool {
1315
14- override def apply (path : Path , conf : Option [List [PatternDef ]], files : Option [Set [Path ]])(implicit spec : Spec ): Try [List [Result ]] = {
15- val completeConf = ToolHelper .getPatternsToLint(conf)
16+ def apply (source : Source .Directory , configuration : Option [List [Pattern .Definition ]], files : Option [Set [Source .File ]])
17+ (implicit specification : Tool .Specification ): Try [List [Result ]] = {
18+ val completeConf = ToolHelper .patternsToLint(configuration)
1619
1720 def isEnabled (issue : Result ) = {
1821 issue match {
19- case Issue (_, _, patternId, _) => completeConf.map (item => item.exists(_.patternId == patternId)).getOrElse( true )
22+ case Result . Issue (_, _, patternId, _) => completeConf.forall (item => item.exists(_.patternId == patternId))
2023 case _ => true
2124 }
2225 }
2326
2427 def buildFileCommands (files : Map [String , Array [String ]]) = {
25- files.map { case (key, values) => commandFor(key, path, completeConf, values) }
28+ files.map { case (key, values) => commandFor(key, completeConf, values) }
2629 .flatMap(item => item.toOption).toList
2730 }
2831
2932 def getStdout (command : List [String ]): Try [List [String ]] = {
3033 Try {
31- CommandRunner .exec(command, Some (path.toFile )) match {
34+ CommandRunner .exec(command, Option ( new File (source.path) )) match {
3235 case Right (resultFromTool) =>
3336 resultFromTool.stdout
34- case Left (failure) => {
37+ case Left (failure) =>
3538 throw failure
36- }
3739 }
3840 }
3941 }
4042
41- val collectedFiles = collectFiles(files, path )
43+ val collectedFiles = collectFiles(files, source )
4244 val classified = classifyFiles(collectedFiles)
43- val commands = classified.map { case item => buildFileCommands(item) }
45+ val commands = classified.map { item => buildFileCommands(item) }
4446 val lines_iterable = commands.map { item => item.map(getStdout) }
4547 val lines = lines_iterable.map {
46- case iterable => iterable.flatMap {
47- case item => item.toOption
48- }.flatten
48+ iterable =>
49+ iterable.flatMap {
50+ item => item.toOption
51+ }.flatten
4952 }
50- lines.map { case line => line.flatMap(parseLine).flatten.filter(isEnabled) }
53+ lines.map { line => line.flatMap(parseLine).flatten.filter(isEnabled) }
5154 }
5255
5356
54- private implicit lazy val writer = Json .reads[Issue ]
55-
5657 private def parseLine (line : String ) = {
5758 val LineRegex = """ (.*?)###(\d*?)###(.*?)###(.*?)""" .r
5859
5960 def createIssue (filename : String , lineNumber : String , message : String , patternId : String ) = {
6061 // If the pylint returns no line put the issue in the first line
6162 val issueLine = if (lineNumber.nonEmpty) lineNumber.toInt else 1
62- Issue (SourcePath (filename),
63- ResultMessage (message),
64- PatternId (patternId),
65- ResultLine (issueLine))
63+ Result . Issue (Source . File (filename),
64+ Result . Message (message),
65+ Pattern . Id (patternId),
66+ Source . Line (issueLine))
6667 }
6768
6869 line match {
6970 case LineRegex (filename, lineNumber, message, patternId) if message.contains(" invalid syntax" ) =>
70- val fileError = FileError (SourcePath (filename),
71+ val fileError = Result . FileError (Source . File (filename),
7172 Option (ErrorMessage (message)))
7273 val issue = createIssue(filename, lineNumber, message, patternId)
7374 Option (List (fileError, issue))
@@ -123,14 +124,14 @@ object Pylint extends Tool {
123124 |classify(items)
124125 """ .stripMargin
125126
126- private def collectFiles (files : Option [Set [Path ]], path : Path ) = {
127- files .collect { case files if files.nonEmpty => files.map(_.toString ) }.getOrElse {
127+ private def collectFiles (filesOpt : Option [Set [Source . File ]], source : Source . Directory ) = {
128+ filesOpt .collect { case files if files.nonEmpty => files.map(_.path ) }.getOrElse {
128129 // if files is empty, let the classification script to find them.
129- List (path.toString )
130+ List (source.path )
130131 }.toList
131132 }
132133
133- def generateClassification (files : List [String ]) = {
134+ def generateClassification (files : List [String ]): String = {
134135 val scriptArgs = files.mkString(" ###" )
135136 val tmp = FileHelper .createTmpFile(classifyScript, " pylint" , " " )
136137 List (" python3" , tmp.toAbsolutePath.toString, scriptArgs).!!
@@ -140,7 +141,7 @@ object Pylint extends Tool {
140141 Try {
141142 val output = generateClassification(files)
142143 val lines = output.split(System .lineSeparator())
143- val parsed = lines.map { case line =>
144+ val parsed = lines.map { line =>
144145 val splitted = line.split(" ###" )
145146 (splitted(0 ), splitted(1 ))
146147 }
@@ -149,16 +150,17 @@ object Pylint extends Tool {
149150 }
150151 }
151152
152- private def commandFor (interpreter : String , path : Path , conf : Option [List [PatternDef ]], files : Array [String ])(implicit spec : Spec ): Try [List [String ]] = {
153+ private def commandFor (interpreter : String , conf : Option [List [Pattern .Definition ]], files : Array [String ])
154+ (implicit specification : Tool .Specification ): Try [List [String ]] = {
153155
154156 val rulesPart = conf.toList.flatMap { conf =>
155157 val rules = conf.map(_.patternId.toString()).mkString(" ," )
156158 List (" --disable=all" , " -e" , rules)
157159 }
158160
159- val configPart = conf.map { case configuration =>
161+ val configPart = conf.map { configuration =>
160162 val confFile = writeConfigFile(configuration)
161- confFile.map { case confPath =>
163+ confFile.map { confPath =>
162164 List (s " --rcfile= $confPath" )
163165 }
164166 }.getOrElse(Success (List .empty[String ]))
@@ -176,10 +178,10 @@ object Pylint extends Tool {
176178 }
177179 }
178180
179- private def writeConfigFile (configuration : List [PatternDef ]): Try [Path ] = {
181+ private def writeConfigFile (configuration : List [Pattern . Definition ]): Try [Path ] = {
180182
181- val parameters = configuration.flatMap { case pattern =>
182- pattern.parameters.getOrElse(Set .empty).map { case param =>
183+ val parameters = configuration.flatMap { pattern =>
184+ pattern.parameters.getOrElse(Set .empty).map { param =>
183185 ParameterHeader .get(param.name) -> param
184186 }
185187 }.groupBy { case (header, _) => header }
@@ -199,8 +201,8 @@ object Pylint extends Tool {
199201 write(paramsToPrint)
200202 }
201203
202- private def generateParameter (parameter : ParameterDef ): String = {
203- val parameterValue = parameter.value match {
204+ private def generateParameter (parameter : Parameter . Definition ): String = {
205+ val parameterValue = ( parameter.value: JsValue ) match {
204206 case JsString (value) => value
205207 case other => Json .stringify(other)
206208 }
@@ -212,7 +214,7 @@ object Pylint extends Tool {
212214 )
213215
214216 private def write (content : String ): Try [Path ] = {
215- randomFile().map { case confFile =>
217+ randomFile().map { confFile =>
216218 Files .write(confFile, content.getBytes)
217219 }
218220 }
0 commit comments