Skip to content

Commit

Permalink
feature: Add support for api tokens :breaking: (#153)
Browse files Browse the repository at this point in the history
Instead of using a project token, users can use an api token and specify username and project name
clean: Move sys.exit to program edge
- Change abstract method run to return int in ConfigurationParsingApp
- Make Components receive Configuration instead of CommandConfiguration

Co-authored-by: Lorenzo Gabriele <[email protected]>
  • Loading branch information
Francisco Duarte and lolgab authored Feb 18, 2020
1 parent d27c46e commit cf8f926
Show file tree
Hide file tree
Showing 14 changed files with 427 additions and 128 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,5 @@ config
.codacy.json
codacy-coverage-reporter-linux-*
codacy-coverage-reporter-darwin-*
classes/
src/test/resources/codacy-coverage.json
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,28 @@ The supported coverage formats can be found [here](https://github.com/codacy/cov

1. Setup the project API token. You can find the token in Project -> Settings -> Integrations -> Project API.

Then set it in your terminal, replacing %Project_Token% with your own token:
1. Set it in your terminal, replacing %Project_Token% with your own token:

```
export CODACY_PROJECT_TOKEN=%Project_Token%
```

##### Alternative: using an API Token

1. Setup the Account API token. You can find the token in Your account -> API tokens

1. Set it in your terminal, replacing the %API_Token% with your own token:

1. Set your project name in your terminal, replacing the %Project_Name%

1. Set your username in your terminal, replacing the %Username%

```
export CODACY_API_TOKEN=%API_Token%
export CODACY_PROJECT_NAME=%Project_Name%
export CODACY_USERNAME=%Username%
```

### Using the script

Additional requirements:
Expand Down
4 changes: 2 additions & 2 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ scalacOptions := Seq(

// Runtime dependencies
libraryDependencies ++= Seq(
"com.codacy" %% "coverage-parser" % "2.5.0",
"com.codacy" %% "coverage-parser" % "2.5.4",
"com.github.alexarchambault" %% "case-app" % "1.2.0",
logbackClassic,
scalaLogging
)

// Test dependencies
libraryDependencies ++= Seq(scalatest).map(_ % "test")
libraryDependencies ++= Seq(scalatest, mockitoScalaScalatest).map(_ % Test)

mainClass in assembly := Some("com.codacy.CodacyCoverageReporter")
assemblyMergeStrategy in assembly := {
Expand Down
2 changes: 1 addition & 1 deletion project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
resolvers := Seq(DefaultMavenRepository, Resolver.jcenterRepo, Resolver.sonatypeRepo("releases"))

addSbtPlugin("com.codacy" % "codacy-sbt-plugin" % "14.0.1")
addSbtPlugin("com.codacy" % "codacy-sbt-plugin" % "18.0.3")

// Publish
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.9")
Expand Down
49 changes: 30 additions & 19 deletions src/main/scala/com/codacy/CodacyCoverageReporter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,44 @@ import com.codacy.di.Components
import com.codacy.helpers.LoggerHelper
import com.codacy.model.configuration.{FinalConfig, ReportConfig}
import com.typesafe.scalalogging.StrictLogging
import com.codacy.rules.ConfigurationRules

object CodacyCoverageReporter extends ConfigurationParsingApp with StrictLogging {

def run(commandConfig: CommandConfiguration): Unit = {
val components = new Components(commandConfig)
def run(commandConfig: CommandConfiguration): Int = {
val noAvailableTokens = commandConfig.baseConfig.projectToken.isEmpty && commandConfig.baseConfig.apiToken.isEmpty
if (commandConfig.baseConfig.skipValue && noAvailableTokens) {
logger.info("Skip reporting coverage")
0
} else {
val result: Either[String, String] = sendReport(commandConfig)
result match {
case Right(message) =>
logger.info(message)
0
case Left(message) =>
logger.error(message)
1
}
}
}

val validatedConfig = components.validatedConfig
private def sendReport(commandConfig: CommandConfiguration) = {
val configRules = new ConfigurationRules(commandConfig)

LoggerHelper.setLoggerLevel(logger, validatedConfig.baseConfig.debug)
configRules.validatedConfig.flatMap { validatedConfig =>
val components = new Components(validatedConfig)
LoggerHelper.setLoggerLevel(logger, validatedConfig.baseConfig.debug)

logger.debug(validatedConfig.toString)
logger.debug(validatedConfig.toString)

val result = validatedConfig match {
case config: ReportConfig =>
components.reportRules.codacyCoverage(config)
validatedConfig match {
case config: ReportConfig =>
components.reportRules.codacyCoverage(config)

case config: FinalConfig =>
components.reportRules.finalReport(config)
case config: FinalConfig =>
components.reportRules.finalReport(config)
}
}

result.fold({ error =>
logger.error(error)
sys.exit(1)
}, { successMessage =>
logger.info(successMessage)
sys.exit(0)
})
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ import com.codacy.configuration.parser.ConfigArgumentParsers._

abstract class ConfigurationParsingApp extends CommandAppWithPreCommand[BaseCommand, CommandConfiguration] {
override final def run(options: CommandConfiguration, remainingArgs: RemainingArgs): Unit = {
run(options)
sys.exit(run(options))
}

def run(config: CommandConfiguration): Unit
def run(config: CommandConfiguration): Int

override def beforeCommand(options: BaseCommand, remainingArgs: Seq[String]): Unit = ()
}
Expand Down Expand Up @@ -55,11 +55,17 @@ case class Report(
case class BaseCommandConfig(
@Name("t") @ValueDescription("your project API token")
projectToken: Option[String],
@Name("a") @ValueDescription("your api token")
apiToken: Option[String],
@Name("u") @ValueDescription("your username")
username: Option[String],
@Name("p") @ValueDescription("project name")
projectName: Option[String],
@ValueDescription("the base URL for the Codacy API")
codacyApiBaseUrl: Option[String],
@ValueDescription("your commitUUID")
commitUUID: Option[String],
@Name("s") @ValueDescription("skip if project token isn't defined")
@Name("s") @ValueDescription("skip if token isn't defined")
skip: Int @@ Counter = Tag.of(0),
@Hidden
debug: Int @@ Counter = Tag.of(0)
Expand Down
23 changes: 12 additions & 11 deletions src/main/scala/com/codacy/di/Components.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,21 @@ package com.codacy.di

import com.codacy.api.client.CodacyClient
import com.codacy.api.service.CoverageServices
import com.codacy.configuration.parser.CommandConfiguration
import com.codacy.model.configuration.Configuration
import com.codacy.rules.{ConfigurationRules, ReportRules}
import com.codacy.model.configuration.{ApiTokenAuthenticationConfig, Configuration, ProjectTokenAuthenticationConfig}
import com.codacy.rules.ReportRules

class Components(private val cmdConfig: CommandConfiguration) {
lazy val validatedConfig: Configuration = configRules.validatedConfig
class Components(private val validatedConfig: Configuration) {
lazy val reportRules = new ReportRules(coverageServices)

lazy val configRules = new ConfigurationRules(cmdConfig)
lazy val reportRules = new ReportRules(validatedConfig, coverageServices)
lazy private val (projectToken, apiToken) = validatedConfig.baseConfig.authentication match {
case ProjectTokenAuthenticationConfig(projectToken) =>
(Some(projectToken), None)
case ApiTokenAuthenticationConfig(apiToken, _, _) =>
(None, Some(apiToken))
}

lazy val codacyClient = new CodacyClient(Some(validatedConfig.baseConfig.codacyApiBaseUrl), apiToken, projectToken)

lazy val codacyClient = new CodacyClient(
Some(validatedConfig.baseConfig.codacyApiBaseUrl),
projectToken = Some(validatedConfig.baseConfig.projectToken)
)
lazy val coverageServices = new CoverageServices(codacyClient)

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,18 @@ case class ReportConfig(

case class FinalConfig(baseConfig: BaseConfig) extends Configuration

case class BaseConfig(projectToken: String, codacyApiBaseUrl: String, commitUUID: Option[CommitUUID], debug: Boolean)
sealed trait AuthenticationConfig

case class ProjectTokenAuthenticationConfig(projectToken: String) extends AuthenticationConfig

case class ApiTokenAuthenticationConfig(apiToken: String, username: String, projectName: String)
extends AuthenticationConfig

case class BaseConfig(
authentication: AuthenticationConfig,
codacyApiBaseUrl: String,
commitUUID: Option[CommitUUID],
debug: Boolean
)

case class CommitUUID(value: String) extends AnyVal
Loading

0 comments on commit cf8f926

Please sign in to comment.