From 7fbf675ecf5b97b5373d7b95ec2f960ea6dda292 Mon Sep 17 00:00:00 2001 From: "david.marinho@codacy.com" Date: Fri, 4 Jul 2025 15:37:34 +0100 Subject: [PATCH 01/11] fix transformation coverage reports --- .gitignore | 5 ++++- src/main/scala/com/codacy/rules/ReportRules.scala | 12 +++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 4a130515..1a025c05 100644 --- a/.gitignore +++ b/.gitignore @@ -32,4 +32,7 @@ musl.tar.gz src/graal/bundle project/metals.sbt site -.bsp \ No newline at end of file +.bsp + +#Ignore vscode AI rules +.github/copilot-instructions.md diff --git a/src/main/scala/com/codacy/rules/ReportRules.scala b/src/main/scala/com/codacy/rules/ReportRules.scala index d5f4631d..5a4b7638 100644 --- a/src/main/scala/com/codacy/rules/ReportRules.scala +++ b/src/main/scala/com/codacy/rules/ReportRules.scala @@ -334,11 +334,13 @@ class ReportRules(coverageServices: => CoverageServices, gitFileFetcher: GitFile logger.warn(s"Report files will not be matched against git files, reason: $error") Seq(new PathPrefixer(config.prefix)) }, - filenames => - Seq(new PathPrefixer(config.prefix), { - val acceptableFileNamesMap = filenames.groupBy(getFilenameFromPath).view.toMap - new GitFileNameUpdaterAndFilter(acceptableFileNamesMap) - }) + filenames => { + val acceptableFileNamesMap = filenames.groupBy(getFilenameFromPath).view.toMap + Seq( + new GitFileNameUpdaterAndFilter(acceptableFileNamesMap), + new PathPrefixer(config.prefix) + ) + } ) transformations.foldLeft(report) { (report, transformation) => From 5f728f046ad1d35c178455b17a4d0380b201455f Mon Sep 17 00:00:00 2001 From: "david.marinho@codacy.com" Date: Fri, 4 Jul 2025 15:46:40 +0100 Subject: [PATCH 02/11] run scalafmt --- .../scala/com/codacy/rules/ReportRules.scala | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/main/scala/com/codacy/rules/ReportRules.scala b/src/main/scala/com/codacy/rules/ReportRules.scala index 5a4b7638..220d4d1a 100644 --- a/src/main/scala/com/codacy/rules/ReportRules.scala +++ b/src/main/scala/com/codacy/rules/ReportRules.scala @@ -329,19 +329,13 @@ class ReportRules(coverageServices: => CoverageServices, gitFileFetcher: GitFile report: CoverageReport )(config: ReportConfig, commitUUID: String, acceptableFileNames: Either[String, Seq[String]]): CoverageReport = { val transformations: Seq[Transformation] = acceptableFileNames - .fold( - error => { - logger.warn(s"Report files will not be matched against git files, reason: $error") - Seq(new PathPrefixer(config.prefix)) - }, - filenames => { + .fold(error => { + logger.warn(s"Report files will not be matched against git files, reason: $error") + Seq(new PathPrefixer(config.prefix)) + }, filenames => { val acceptableFileNamesMap = filenames.groupBy(getFilenameFromPath).view.toMap - Seq( - new GitFileNameUpdaterAndFilter(acceptableFileNamesMap), - new PathPrefixer(config.prefix) - ) - } - ) + Seq(new GitFileNameUpdaterAndFilter(acceptableFileNamesMap), new PathPrefixer(config.prefix)) + }) transformations.foldLeft(report) { (report, transformation) => transformation.execute(report) From 59c2712dcbc7561deb8d3bc71a51a9cf865d24fb Mon Sep 17 00:00:00 2001 From: "david.marinho@codacy.com" Date: Fri, 4 Jul 2025 16:12:55 +0100 Subject: [PATCH 03/11] bump circleci-cli version --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 49a04d7e..a772c1a1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,12 +1,12 @@ version: 2.1 orbs: - codacy: codacy/base@12.1.2 + codacy: codacy/base@12.2.0 references: circleci_job: &circleci_job docker: - - image: circleci/circleci-cli:0.1.29041 + - image: circleci/circleci-cli:0.1.9 working_directory: ~/workdir commands: From 648a29f53c02270f3d1eab57501fcd642a6dd850 Mon Sep 17 00:00:00 2001 From: "david.marinho@codacy.com" Date: Fri, 4 Jul 2025 16:14:39 +0100 Subject: [PATCH 04/11] bump circleci-cli version --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index a772c1a1..c28756ed 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -6,7 +6,7 @@ orbs: references: circleci_job: &circleci_job docker: - - image: circleci/circleci-cli:0.1.9 + - image: circleci/circleci-cli:0.1.32638 working_directory: ~/workdir commands: From 6834c3dc15b769f298127e718325c94341abad61 Mon Sep 17 00:00:00 2001 From: "david.marinho@codacy.com" Date: Fri, 4 Jul 2025 16:20:49 +0100 Subject: [PATCH 05/11] refactor URL to URI --- .../com/codacy/api/client/CodacyClient.scala | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/api-scala/src/main/scala/com/codacy/api/client/CodacyClient.scala b/api-scala/src/main/scala/com/codacy/api/client/CodacyClient.scala index 99f32d4a..f5d69703 100644 --- a/api-scala/src/main/scala/com/codacy/api/client/CodacyClient.scala +++ b/api-scala/src/main/scala/com/codacy/api/client/CodacyClient.scala @@ -4,7 +4,7 @@ import play.api.libs.json._ import com.codacy.api.util.JsonOps import scalaj.http.{Http, HttpOptions} -import java.net.URL +import java.net.{URI, URL} import scala.util.{Failure, Success, Try} import scala.util.control.NonFatal @@ -23,11 +23,12 @@ class CodacyClient( private val tokens = Map.empty[String, String] ++ apiToken.map(t => "api-token" -> t) ++ projectToken.map(t => "project-token" -> t) ++ - // This is deprecated and is kept for backward compatibility. It will removed in the context of CY-1272 + // This is deprecated and is kept for backward compatibility. It will be removed in the context of CY-1272 apiToken.map(t => "api_token" -> t) ++ projectToken.map(t => "project_token" -> t) - private val remoteUrl = new URL(new URL(apiUrl.getOrElse("https://api.codacy.com")), "/2.0").toString() + private val baseUri = new URI(apiUrl.getOrElse("https://api.codacy.com")) + private val remoteUrl = baseUri.resolve("/2.0").toURL.toString private def httpOptions = if (allowUnsafeSSL) Seq(HttpOptions.allowUnsafeSSL) else Seq.empty @@ -62,11 +63,12 @@ class CodacyClient( parseJsonAs[T](body) match { case failure: FailedResponse => - retryPost(request, value, timeoutOpt, sleepTime, numRetries.map(x => x - 1), failure.message) + retryPost(request, value, timeoutOpt, sleepTime, numRetries.map(_ - 1), failure.message) case success => success } } catch { - case NonFatal(ex) => retryPost(request, value, timeoutOpt, sleepTime, numRetries.map(x => x - 1), ex.getMessage) + case NonFatal(ex) => + retryPost(request, value, timeoutOpt, sleepTime, numRetries.map(_ - 1), ex.getMessage) } } @@ -78,9 +80,9 @@ class CodacyClient( numRetries: Option[Int], failureMessage: String )(implicit reads: Reads[T]): RequestResponse[T] = { - if (numRetries.exists(x => x > 0)) { - sleepTime.map(x => Thread.sleep(x)) - post(request, value, timeoutOpt, sleepTime, numRetries.map(x => x - 1)) + if (numRetries.exists(_ > 0)) { + sleepTime.foreach(Thread.sleep) + post(request, value, timeoutOpt, sleepTime, numRetries.map(_ - 1)) } else { RequestResponse.failure( s"Error doing a post to $remoteUrl/${request.endpoint}: exhausted retries due to $failureMessage" @@ -92,21 +94,20 @@ class CodacyClient( parseJson(input) match { case failure: FailedResponse => failure case SuccessfulResponse(json) => - json - .validate[T] - .fold( - errors => FailedResponse(JsonOps.handleConversionFailure(errors)), - converted => SuccessfulResponse(converted) - ) + json.validate[T].fold( + errors => FailedResponse(JsonOps.handleConversionFailure(errors)), + converted => SuccessfulResponse(converted) + ) } } private def parseJson(input: String): RequestResponse[JsValue] = { Try(Json.parse(input)) match { case Success(json) => - json - .validate[ErrorJson] - .fold(_ => SuccessfulResponse(json), apiError => FailedResponse(s"API Error: ${apiError.error}")) + json.validate[ErrorJson].fold( + _ => SuccessfulResponse(json), + apiError => FailedResponse(s"API Error: ${apiError.error}") + ) case Failure(exception) => FailedResponse(s"Failed to parse API response as JSON: $input\nUnderlying exception - ${exception.getMessage}") } From 86b1c4536d3c112a3063b645b3bcad383984d3cc Mon Sep 17 00:00:00 2001 From: "david.marinho@codacy.com" Date: Fri, 4 Jul 2025 16:23:33 +0100 Subject: [PATCH 06/11] run scalafmt --- .../com/codacy/api/client/CodacyClient.scala | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/api-scala/src/main/scala/com/codacy/api/client/CodacyClient.scala b/api-scala/src/main/scala/com/codacy/api/client/CodacyClient.scala index f5d69703..a7e92571 100644 --- a/api-scala/src/main/scala/com/codacy/api/client/CodacyClient.scala +++ b/api-scala/src/main/scala/com/codacy/api/client/CodacyClient.scala @@ -94,20 +94,21 @@ class CodacyClient( parseJson(input) match { case failure: FailedResponse => failure case SuccessfulResponse(json) => - json.validate[T].fold( - errors => FailedResponse(JsonOps.handleConversionFailure(errors)), - converted => SuccessfulResponse(converted) - ) + json + .validate[T] + .fold( + errors => FailedResponse(JsonOps.handleConversionFailure(errors)), + converted => SuccessfulResponse(converted) + ) } } private def parseJson(input: String): RequestResponse[JsValue] = { Try(Json.parse(input)) match { case Success(json) => - json.validate[ErrorJson].fold( - _ => SuccessfulResponse(json), - apiError => FailedResponse(s"API Error: ${apiError.error}") - ) + json + .validate[ErrorJson] + .fold(_ => SuccessfulResponse(json), apiError => FailedResponse(s"API Error: ${apiError.error}")) case Failure(exception) => FailedResponse(s"Failed to parse API response as JSON: $input\nUnderlying exception - ${exception.getMessage}") } From 3c9d700c0fa879557b71ce91a6c981fb46790e0f Mon Sep 17 00:00:00 2001 From: "david.marinho@codacy.com" Date: Fri, 4 Jul 2025 18:39:46 +0100 Subject: [PATCH 07/11] fix sleep --- .../scala/com/codacy/api/client/CodacyClient.scala | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/api-scala/src/main/scala/com/codacy/api/client/CodacyClient.scala b/api-scala/src/main/scala/com/codacy/api/client/CodacyClient.scala index a7e92571..055a6c0c 100644 --- a/api-scala/src/main/scala/com/codacy/api/client/CodacyClient.scala +++ b/api-scala/src/main/scala/com/codacy/api/client/CodacyClient.scala @@ -63,12 +63,12 @@ class CodacyClient( parseJsonAs[T](body) match { case failure: FailedResponse => - retryPost(request, value, timeoutOpt, sleepTime, numRetries.map(_ - 1), failure.message) + retryPost(request, value, timeoutOpt, sleepTime, numRetries.map(x => x - 1), failure.message) case success => success } } catch { case NonFatal(ex) => - retryPost(request, value, timeoutOpt, sleepTime, numRetries.map(_ - 1), ex.getMessage) + retryPost(request, value, timeoutOpt, sleepTime, numRetries.map(x => x - 1), ex.getMessage) } } @@ -80,9 +80,9 @@ class CodacyClient( numRetries: Option[Int], failureMessage: String )(implicit reads: Reads[T]): RequestResponse[T] = { - if (numRetries.exists(_ > 0)) { - sleepTime.foreach(Thread.sleep) - post(request, value, timeoutOpt, sleepTime, numRetries.map(_ - 1)) + if (numRetries.exists(x => x > 0)) { + sleepTime.map(x => Thread.sleep(x)) + post(request, value, timeoutOpt, sleepTime, numRetries.map(x => x - 1)) } else { RequestResponse.failure( s"Error doing a post to $remoteUrl/${request.endpoint}: exhausted retries due to $failureMessage" From ae64370efe4921afb121493597c05021efbe8ffe Mon Sep 17 00:00:00 2001 From: "david.marinho@codacy.com" Date: Fri, 4 Jul 2025 18:50:36 +0100 Subject: [PATCH 08/11] fix URL --- src/main/scala/com/codacy/rules/ConfigurationRules.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/com/codacy/rules/ConfigurationRules.scala b/src/main/scala/com/codacy/rules/ConfigurationRules.scala index 6902ad35..6ed3d32c 100644 --- a/src/main/scala/com/codacy/rules/ConfigurationRules.scala +++ b/src/main/scala/com/codacy/rules/ConfigurationRules.scala @@ -4,7 +4,7 @@ import com.codacy.api.OrganizationProvider import com.codacy.api.client.RequestTimeout import java.io.File -import java.net.URL +import java.net.{URI, URL} import scala.util.Try import wvlet.log.LogSupport import com.codacy.configuration.parser.{BaseCommandConfig, CommandConfiguration, Final, Report} @@ -176,7 +176,7 @@ class ConfigurationRules(cmdConfig: CommandConfiguration, envVars: Map[String, S * @return true for valid url, false if not */ private[rules] def validUrl(baseUrl: String): Boolean = { - Try(new URL(baseUrl)).toOption.isDefined + Try(new URI(baseUrl)).toOption.isDefined } /** From 10da5b300ffadca328999041589c183ccab40f0e Mon Sep 17 00:00:00 2001 From: "david.marinho@codacy.com" Date: Fri, 4 Jul 2025 19:25:32 +0100 Subject: [PATCH 09/11] fix URL again --- src/main/scala/com/codacy/rules/ConfigurationRules.scala | 2 +- .../rules/commituuid/providers/GitHubActionProviderSpec.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/com/codacy/rules/ConfigurationRules.scala b/src/main/scala/com/codacy/rules/ConfigurationRules.scala index 6ed3d32c..b23fb196 100644 --- a/src/main/scala/com/codacy/rules/ConfigurationRules.scala +++ b/src/main/scala/com/codacy/rules/ConfigurationRules.scala @@ -176,7 +176,7 @@ class ConfigurationRules(cmdConfig: CommandConfiguration, envVars: Map[String, S * @return true for valid url, false if not */ private[rules] def validUrl(baseUrl: String): Boolean = { - Try(new URI(baseUrl)).toOption.isDefined + Try(new URL(baseUrl)).toOption.isDefined } /** diff --git a/src/test/scala/com/codacy/rules/commituuid/providers/GitHubActionProviderSpec.scala b/src/test/scala/com/codacy/rules/commituuid/providers/GitHubActionProviderSpec.scala index ff4ff968..8f1e5ce2 100644 --- a/src/test/scala/com/codacy/rules/commituuid/providers/GitHubActionProviderSpec.scala +++ b/src/test/scala/com/codacy/rules/commituuid/providers/GitHubActionProviderSpec.scala @@ -27,7 +27,7 @@ class GitHubActionProviderSpec extends AnyWordSpec with Matchers with EitherValu val envVars = Map( "GITHUB_EVENT_NAME" -> "pull_request", "GITHUB_SHA" -> invalidPullRequestCommitUuid, - "GITHUB_EVENT_PATH" -> "src/test/resources/invalid-github-action-pull-request-event.json" + "GITHUB_EVENT_PATH" -> "src/test/resources/invalid-github-action-event.json" ) val commitUuidEither = provider.getValidCommitUUID(envVars) commitUuidEither should be(Symbol("left")) From 8003ddd591d9e60256fa605f424eafad9ee6662e Mon Sep 17 00:00:00 2001 From: "david.marinho@codacy.com" Date: Fri, 4 Jul 2025 19:58:49 +0100 Subject: [PATCH 10/11] fix validUrl with the new URI --- src/main/scala/com/codacy/rules/ConfigurationRules.scala | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/scala/com/codacy/rules/ConfigurationRules.scala b/src/main/scala/com/codacy/rules/ConfigurationRules.scala index b23fb196..6df3eeed 100644 --- a/src/main/scala/com/codacy/rules/ConfigurationRules.scala +++ b/src/main/scala/com/codacy/rules/ConfigurationRules.scala @@ -176,9 +176,14 @@ class ConfigurationRules(cmdConfig: CommandConfiguration, envVars: Map[String, S * @return true for valid url, false if not */ private[rules] def validUrl(baseUrl: String): Boolean = { - Try(new URL(baseUrl)).toOption.isDefined + Try(new URI(baseUrl.trim)).toOption.exists { uri => + val scheme = uri.getScheme + val host = uri.getHost + scheme != null && + (scheme.equalsIgnoreCase("http") || scheme.equalsIgnoreCase("https")) && + host != null && host.nonEmpty + } } - /** * Validate report files option * From df7967e2afb19351e72b3494898bc5eacebe62ea Mon Sep 17 00:00:00 2001 From: "david.marinho@codacy.com" Date: Fri, 4 Jul 2025 20:09:40 +0100 Subject: [PATCH 11/11] run scalafmt --- src/main/scala/com/codacy/rules/ConfigurationRules.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/scala/com/codacy/rules/ConfigurationRules.scala b/src/main/scala/com/codacy/rules/ConfigurationRules.scala index 6df3eeed..48656bcd 100644 --- a/src/main/scala/com/codacy/rules/ConfigurationRules.scala +++ b/src/main/scala/com/codacy/rules/ConfigurationRules.scala @@ -177,13 +177,14 @@ class ConfigurationRules(cmdConfig: CommandConfiguration, envVars: Map[String, S */ private[rules] def validUrl(baseUrl: String): Boolean = { Try(new URI(baseUrl.trim)).toOption.exists { uri => - val scheme = uri.getScheme - val host = uri.getHost + val scheme = uri.getScheme + val host = uri.getHost scheme != null && (scheme.equalsIgnoreCase("http") || scheme.equalsIgnoreCase("https")) && host != null && host.nonEmpty } } + /** * Validate report files option *