diff --git a/Dockerfile b/Dockerfile index 12be8c44..dae25874 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,10 +29,6 @@ RUN bundle config set --local path 'vendor/bundle' && bundle install && gem clea FROM $BASE_IMAGE -ARG GEM_FOLDER -ENV GEM_HOME=$GEM_FOLDER -ENV PATH $GEM_HOME/bin:$GEM_HOME/gems/bin:$PATH - RUN apk add --no-cache ruby ruby-etc ruby-dev ruby-irb ruby-rake ruby-io-console ruby-bigdecimal ruby-json \ openjdk17-jre \ bash diff --git a/Gemfile.lock b/Gemfile.lock index ae62453f..6c1d57ea 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -108,7 +108,7 @@ GEM git_diff_parser (3.2.0) globalid (1.2.1) activesupport (>= 6.1) - graphql (2.3.6) + graphql (2.3.7) base64 haml (6.3.0) temple (>= 0.8.2) @@ -143,7 +143,7 @@ GEM matrix (0.4.2) method_source (1.1.0) mini_mime (1.1.5) - minitest (5.24.0) + minitest (5.24.1) mocha (2.4.0) ruby2_keywords (>= 0.0.5) msgpack (1.7.2) @@ -158,8 +158,18 @@ GEM net-smtp (0.5.0) net-protocol nio4r (2.7.3) + nokogiri (1.16.6-aarch64-linux) + racc (~> 1.4) + nokogiri (1.16.6-arm-linux) + racc (~> 1.4) + nokogiri (1.16.6-arm64-darwin) + racc (~> 1.4) + nokogiri (1.16.6-x86-linux) + racc (~> 1.4) nokogiri (1.16.6-x86_64-darwin) racc (~> 1.4) + nokogiri (1.16.6-x86_64-linux) + racc (~> 1.4) parallel (1.25.1) parser (3.3.3.0) ast (~> 2.4.1) @@ -266,7 +276,7 @@ GEM rubocop-performance (1.21.1) rubocop (>= 1.48.1, < 2.0) rubocop-ast (>= 1.31.1, < 2.0) - rubocop-rails (2.25.0) + rubocop-rails (2.25.1) activesupport (>= 4.2.0) rack (>= 1.1) rubocop (>= 1.33.0, < 2.0) @@ -313,7 +323,16 @@ GEM actionpack (>= 6.1) activesupport (>= 6.1) sprockets (>= 3.0.0) + sqlite3 (2.0.2-aarch64-linux-gnu) + sqlite3 (2.0.2-aarch64-linux-musl) + sqlite3 (2.0.2-arm-linux-gnu) + sqlite3 (2.0.2-arm-linux-musl) + sqlite3 (2.0.2-arm64-darwin) + sqlite3 (2.0.2-x86-linux-gnu) + sqlite3 (2.0.2-x86-linux-musl) sqlite3 (2.0.2-x86_64-darwin) + sqlite3 (2.0.2-x86_64-linux-gnu) + sqlite3 (2.0.2-x86_64-linux-musl) standard (1.39.0) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.0) @@ -342,7 +361,7 @@ GEM syntax_tree (>= 2.0.1) temple (0.10.3) thor (1.3.1) - tilt (2.3.0) + tilt (2.4.0) timeout (0.4.1) turbo-rails (2.0.5) actionpack (>= 6.0.0) @@ -368,7 +387,20 @@ GEM zeitwerk (2.6.16) PLATFORMS - x86_64-darwin-23 + aarch64-linux + aarch64-linux-gnu + aarch64-linux-musl + arm-linux + arm-linux-gnu + arm-linux-musl + arm64-darwin + x86-linux + x86-linux-gnu + x86-linux-musl + x86_64-darwin + x86_64-linux + x86_64-linux-gnu + x86_64-linux-musl DEPENDENCIES actioncable @@ -425,4 +457,4 @@ DEPENDENCIES yard BUNDLED WITH - 2.5.7 + 2.5.14 diff --git a/docs/description/Rails_LinkToBlank.md b/docs/description/Rails_LinkToBlank.md index ee58ab5a..7bfa75dc 100644 --- a/docs/description/Rails_LinkToBlank.md +++ b/docs/description/Rails_LinkToBlank.md @@ -1,5 +1,5 @@ -Checks for calls to `link_to` that contain a +Checks for calls to `link_to`, `link_to_if`, and `link_to_unless` methods that contain a `target: '_blank'` but no `rel: 'noopener'`. This can be a security risk as the loaded page will have control over the previous page and could change its location for phishing purposes. diff --git a/docs/description/Rails_Validation.md b/docs/description/Rails_Validation.md index bcbfdf9f..8d8aad10 100644 --- a/docs/description/Rails_Validation.md +++ b/docs/description/Rails_Validation.md @@ -6,6 +6,7 @@ Checks for the use of old-style attribute validation macros. ```ruby # bad validates_acceptance_of :foo +validates_comparison_of :foo validates_confirmation_of :foo validates_exclusion_of :foo validates_format_of :foo @@ -20,6 +21,7 @@ validates_uniqueness_of :foo # good validates :foo, acceptance: true validates :foo, confirmation: true +validates :foo, comparison: true validates :foo, exclusion: true validates :foo, format: true validates :foo, inclusion: true diff --git a/docs/description/description.json b/docs/description/description.json index c767392a..2b47a9fc 100644 --- a/docs/description/description.json +++ b/docs/description/description.json @@ -8665,6 +8665,10 @@ "description": "Use methods that skips model validations with caution. See reference for more information.", "timeToFix": 5, "parameters": [ + { + "name": "Safe", + "description": "Safe" + }, { "name": "ForbiddenMethods", "description": "ForbiddenMethods" @@ -8949,7 +8953,13 @@ "patternId": "Rails_WhereRange", "title": "Use ranges in `where` instead of manually constructing SQL.", "description": "Use ranges in `where` instead of manually constructing SQL.", - "timeToFix": 5 + "timeToFix": 5, + "parameters": [ + { + "name": "SafeAutoCorrect", + "description": "SafeAutoCorrect" + } + ] }, { "patternId": "Sorbet_BindingConstantWithoutTypeAlias", diff --git a/docs/patterns.json b/docs/patterns.json index 17849323..3509d0de 100644 --- a/docs/patterns.json +++ b/docs/patterns.json @@ -9816,6 +9816,10 @@ "level": "Warning", "category": "ErrorProne", "parameters": [ + { + "name": "Safe", + "default": "false" + }, { "name": "ForbiddenMethods", "default": [ @@ -10155,6 +10159,12 @@ "patternId": "Rails_WhereRange", "level": "Warning", "category": "ErrorProne", + "parameters": [ + { + "name": "SafeAutoCorrect", + "default": "false" + } + ], "enabled": false }, { diff --git a/src/main/scala/codacy/rubocop/Rubocop.scala b/src/main/scala/codacy/rubocop/Rubocop.scala index 92536922..0956da66 100644 --- a/src/main/scala/codacy/rubocop/Rubocop.scala +++ b/src/main/scala/codacy/rubocop/Rubocop.scala @@ -13,7 +13,7 @@ import com.codacy.tools.scala.seed.utils.CommandRunner import play.api.libs.json._ import scala.io.Source -import scala.util.{Failure, Properties, Success, Try} +import scala.util.{Failure, Properties, Try} object Rubocop extends Tool { private val plugins: List[String] = @@ -45,51 +45,36 @@ object Rubocop extends Tool { files: Option[Set[api.Source.File]], options: Map[Options.Key, Options.Value] )(implicit specification: Tool.Specification): Try[List[Result]] = { - val cmd = getCommandFor(Paths.get(source.path), configuration, files, specification, resultFilePath) CommandRunner.exec(cmd, Some(new File(source.path))) match { - - case Right(resultFromTool) if resultFromTool.exitCode < 2 => - parseResult(resultFilePath.toFile) match { - case s @ Success(_) => s - case Failure(e) => + case Right(resultFromTool) => + Try(parseResult(resultFilePath.toFile)).recover { + case e => val msg = s""" - |Rubocop exited with code ${resultFromTool.exitCode} - |message: ${e.getMessage} - |stdout: ${resultFromTool.stdout.mkString(Properties.lineSeparator)} - |stderr: ${resultFromTool.stderr.mkString(Properties.lineSeparator)} - """.stripMargin - Failure(new Exception(msg)) + |Rubocop exited with code ${resultFromTool.exitCode} + |message: ${e.getMessage} + |stdout: ${resultFromTool.stdout.mkString(Properties.lineSeparator)} + |stderr: ${resultFromTool.stderr.mkString(Properties.lineSeparator)} + """.stripMargin + List.empty[Result] } - case Right(resultFromTool) => - val msg = - s""" - |Rubocop exited with code ${resultFromTool.exitCode} - |stdout: ${resultFromTool.stdout.mkString(Properties.lineSeparator)} - |stderr: ${resultFromTool.stderr.mkString(Properties.lineSeparator)} - """.stripMargin - Failure(new Exception(msg)) - case Left(e) => Failure(e) } } - private[this] def parseResult(filename: File): Try[List[Result]] = { - Try { - val resultFromTool = Source.fromFile(filename).getLines().mkString - Json.parse(resultFromTool) - }.flatMap { json => - json.validate[RubocopResult] match { - case JsSuccess(rubocopResult, _) => - Success(rubocopResult.files.getOrElse(List.empty).flatMap { file => - ruboFileToResult(file) - }) - case JsError(err) => - Failure(new Throwable(Json.stringify(JsError.toJson(err)))) - } + private[this] def parseResult(filename: File): List[Result] = { + val resultFromTool = Source.fromFile(filename).getLines().mkString + val json = Json.parse(resultFromTool) + json.validate[RubocopResult] match { + case JsSuccess(rubocopResult, _) => + Success(rubocopResult.files.getOrElse(List.empty).flatMap { file => + ruboFileToResult(file) + }) + case JsError(_) => + List.empty[Result] // Return an empty list in case of parsing errors } }