Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BE2] Integration of linter in the main code #1914

Merged
merged 12 commits into from
Jun 19, 2024
19 changes: 15 additions & 4 deletions be2-scala/.scalafix.conf
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
rules = [
DisableSyntax,
OrganizeImports,
RedundantSyntax
ArraysInFormat,
CatchNpe,
ComparingFloatingTypes,
EmptyInterpolatedString,
IllegalFormatString,
ImpossibleOptionSizeCondition,
IncorrectlyNamedExceptions,
IncorrectNumberOfArgsToFormat,
LonelySealedTrait,
MapGetAndGetOrElse,
NanComparison,
OptionGet,
OptionSize,
StripMarginOnRegex,
TryGet
]
OrganizeImports.removeUnused = false
161 changes: 83 additions & 78 deletions be2-scala/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@ scalaVersion := "3.3.1"

// Recommended 2.13 Scala flags (https://nathankleyn.com/2019/05/13/recommended-scalac-flags-for-2-13) slightly adapted for PoP
scalacOptions ++= Seq(
"-deprecation", // Emit warning and location for usages of deprecated APIs.
"-explain", // Explain type errors in more detail.
"-feature", // Emit warning and location for usages of features that should be imported explicitly.
"-language:existentials", // Existential types (besides wildcard types) can be written and inferred
"-language:experimental.macros", // Allow macro definition (besides implementation and application)
"-language:higherKinds", // Allow higher-kinded types
"-language:implicitConversions", // Allow definition of implicit functions called views
"-unchecked", // Enable additional warnings where generated code depends on assumptions.
"-Ysafe-init", // Wrap field accessors to throw an exception on uninitialized access.
"-Xfatal-warnings" // Fail the compilation if there are any warnings.
"-deprecation", // Emit warning and location for usages of deprecated APIs.
"-explain", // Explain type errors in more detail.
"-feature", // Emit warning and location for usages of features that should be imported explicitly.
"-language:existentials", // Existential types (besides wildcard types) can be written and inferred
"-language:experimental.macros", // Allow macro definition (besides implementation and application)
"-language:higherKinds", // Allow higher-kinded types
"-language:implicitConversions", // Allow definition of implicit functions called views
"-unchecked", // Enable additional warnings where generated code depends on assumptions.
"-Ysafe-init", // Wrap field accessors to throw an exception on uninitialized access.
"-Xfatal-warnings" // Fail the compilation if there are any warnings.
)

// Reload changes automatically
Expand All @@ -30,9 +30,9 @@ Compile / run / connectInput := true
// This allows the system properties (-D...) to be passed to the fork
// Code from: https://stackoverflow.com/a/54326800
Compile / run / javaOptions ++= {
sys.props.toList.map {
case (key, value) => s"-D$key=$value"
}
sys.props.toList.map {
case (key, value) => s"-D$key=$value"
}
}

// Make test execution synchronized
Expand All @@ -41,23 +41,23 @@ Test / test / parallelExecution := false
// Create task to copy the protocol folder to resources
lazy val copyProtocolTask = taskKey[Unit]("Copy protocol to resources")
copyProtocolTask := {
val log = streams.value.log
log.info("Executing Protocol folder copy...")
val scalaDest = "be2-scala"
baseDirectory.value.name

if (!baseDirectory.value.name.equals(scalaDest)) {
log.error(s"Please make sure you working dir is $scalaDest !")
} else {
val source = new File("../protocol")
val dest = new File("./src/main/resources/protocol")
Try(IO.copyDirectory(source, dest, overwrite = true)) match {
case Success(_) => log.info("Copied protocol folder in ./src/main/resources")
case Failure(exception) =>
log.error("Could not copy protocol to resource folder")
exception.printStackTrace()
val log = streams.value.log
log.info("Executing Protocol folder copy...")
val scalaDest = "be2-scala"
baseDirectory.value.name

if (!baseDirectory.value.name.equals(scalaDest)) {
log.error(s"Please make sure you working dir is $scalaDest !")
} else {
val source = new File("../protocol")
val dest = new File("./src/main/resources/protocol")
Try(IO.copyDirectory(source, dest, overwrite = true)) match {
case Success(_) => log.info("Copied protocol folder in ./src/main/resources")
case Failure(exception) =>
log.error("Could not copy protocol to resource folder")
exception.printStackTrace()
}
}
}
}

// Add the copyProtocolTask to compile and test scopes
Expand All @@ -76,54 +76,51 @@ Compile / run / mainClass := Some("ch.epfl.pop.Server")
Compile / packageBin / mainClass := Some("ch.epfl.pop.Server")

lazy val scoverageSettings = Seq(
Compile / coverageEnabled := true,
Test / coverageEnabled := true,
packageBin / coverageEnabled := false
Compile / coverageEnabled := true,
Test / coverageEnabled := true,
packageBin / coverageEnabled := false
)

// Scalafix
semanticdbEnabled := true

// Configure Sonar
sonarProperties := Map(
"sonar.organization" -> "dedis",
"sonar.projectKey" -> "dedis_popstellar_be2",
"sonar.sources" -> "src/main/scala",
"sonar.tests" -> "src/test/scala",
"sonar.sourceEncoding" -> "UTF-8",
"sonar.scala.version" -> "3.3.1",
// Paths to the test and coverage reports
"sonar.scala.coverage.reportPaths" -> "./target/scala-3.3.1/scoverage-report/scoverage.xml",
"sonar.scala.scapegoat.reportPaths" -> "./target/scala-3.3.1/scapegoat-report/scapegoat.xml"
"sonar.organization" -> "dedis",
"sonar.projectKey" -> "dedis_popstellar_be2",
"sonar.sources" -> "src/main/scala",
"sonar.tests" -> "src/test/scala",
"sonar.sourceEncoding" -> "UTF-8",
"sonar.scala.version" -> "3.3.1",
// Paths to the test and coverage reports
"sonar.scala.coverage.reportPaths" -> "./target/scala-3.3.1/scoverage-report/scoverage.xml",
"sonar.scala.scapegoat.reportPaths" -> "./target/scala-3.3.1/scapegoat-report/scapegoat.xml"
)

assembly / assemblyMergeStrategy := {
case PathList("module-info.class") => MergeStrategy.discard
case PathList("reference.conf") => MergeStrategy.concat
case PathList("META-INF", "MANIFEST.MF") => MergeStrategy.discard
case PathList("META-INF", "LICENSE") => MergeStrategy.concat
case PathList("META-INF", "INDEX.LIST") => MergeStrategy.concat
case PathList("META-INF", "NOTICE") => MergeStrategy.discard
case PathList("META-INF", "services", "com.fasterxml.jackson.core.ObjectCodec") => MergeStrategy.first
case PathList("META-INF", "services", "com.fasterxml.jackson.core.JsonFactory") => MergeStrategy.first
case PathList("META-INF", "versions", "9", "module-info.class") => MergeStrategy.first

case PathList("google", "protobuf", "api.proto") => MergeStrategy.first
case PathList("google", "protobuf", "struct.proto") => MergeStrategy.first
case PathList("google", "protobuf", "field_mask.proto") => MergeStrategy.first
case PathList("google", "protobuf", "duration.proto") => MergeStrategy.first
case PathList("google", "protobuf", "timestamp.proto") => MergeStrategy.first
case PathList("google", "protobuf", "source_context.proto") => MergeStrategy.first
case PathList("google", "protobuf", "empty.proto") => MergeStrategy.first
case PathList("google", "protobuf", "descriptor.proto") => MergeStrategy.first
case PathList("google", "protobuf", "wrappers.proto") => MergeStrategy.first
case PathList("google", "protobuf", "any.proto") => MergeStrategy.first
case PathList("google", "protobuf", "type.proto") => MergeStrategy.first

// exclude digital signatures because the merging process can invalidate them
case PathList(ps @ _*) if Seq(".SF", ".DSA", ".RSA").exists(ps.last.endsWith(_)) =>
MergeStrategy.discard
case _ => MergeStrategy.defaultMergeStrategy("")
case PathList("module-info.class") => MergeStrategy.discard
case PathList("reference.conf") => MergeStrategy.concat
case PathList("META-INF", "MANIFEST.MF") => MergeStrategy.discard
case PathList("META-INF", "LICENSE") => MergeStrategy.concat
case PathList("META-INF", "INDEX.LIST") => MergeStrategy.concat
case PathList("META-INF", "NOTICE") => MergeStrategy.discard
case PathList("META-INF", "services", "com.fasterxml.jackson.core.ObjectCodec") => MergeStrategy.first
case PathList("META-INF", "services", "com.fasterxml.jackson.core.JsonFactory") => MergeStrategy.first
case PathList("META-INF", "versions", "9", "module-info.class") => MergeStrategy.first

case PathList("google", "protobuf", "api.proto") => MergeStrategy.first
case PathList("google", "protobuf", "struct.proto") => MergeStrategy.first
case PathList("google", "protobuf", "field_mask.proto") => MergeStrategy.first
case PathList("google", "protobuf", "duration.proto") => MergeStrategy.first
case PathList("google", "protobuf", "timestamp.proto") => MergeStrategy.first
case PathList("google", "protobuf", "source_context.proto") => MergeStrategy.first
case PathList("google", "protobuf", "empty.proto") => MergeStrategy.first
case PathList("google", "protobuf", "descriptor.proto") => MergeStrategy.first
case PathList("google", "protobuf", "wrappers.proto") => MergeStrategy.first
case PathList("google", "protobuf", "any.proto") => MergeStrategy.first
case PathList("google", "protobuf", "type.proto") => MergeStrategy.first

// exclude digital signatures because the merging process can invalidate them
case PathList(ps @ _*) if Seq(".SF", ".DSA", ".RSA").exists(ps.last.endsWith(_)) =>
MergeStrategy.discard
case _ => MergeStrategy.defaultMergeStrategy("")
}

// ------------------------ DEPENDENCIES ------------------------ 77
Expand All @@ -134,14 +131,14 @@ val AkkaVersion = "2.9.1"
val AkkaHttpVersion = "10.6.0"

libraryDependencies ++= Seq(
"com.typesafe.akka" %% "akka-stream-typed" % AkkaVersion, // Akka streams (Graph)
"com.typesafe.akka" %% "akka-http" % AkkaHttpVersion, // Akka http (WebSockets)
"com.typesafe.akka" %% "akka-cluster-tools" % AkkaVersion, // Akka distributed publish/subscribe cluster

"ch.qos.logback" % "logback-classic" % "1.4.14" % Runtime, // Akka logging library
"com.typesafe.akka" %% "akka-testkit" % AkkaVersion % Test, // Akka actor test kit (akka actor testing library)
"com.typesafe.akka" %% "akka-stream-testkit" % AkkaVersion, // Akka stream test kit
"com.typesafe.akka" %% "akka-http-testkit" % AkkaHttpVersion // Akka http test kit
"com.typesafe.akka" %% "akka-stream-typed" % AkkaVersion, // Akka streams (Graph)
"com.typesafe.akka" %% "akka-http" % AkkaHttpVersion, // Akka http (WebSockets)
"com.typesafe.akka" %% "akka-cluster-tools" % AkkaVersion, // Akka distributed publish/subscribe cluster

"ch.qos.logback" % "logback-classic" % "1.4.14" % Runtime, // Akka logging library
"com.typesafe.akka" %% "akka-testkit" % AkkaVersion % Test, // Akka actor test kit (akka actor testing library)
"com.typesafe.akka" %% "akka-stream-testkit" % AkkaVersion, // Akka stream test kit
"com.typesafe.akka" %% "akka-http-testkit" % AkkaHttpVersion // Akka http test kit
)

// LevelDB database
Expand Down Expand Up @@ -173,3 +170,11 @@ libraryDependencies += "com.google.zxing" % "core" % "3.5.1"
libraryDependencies += "com.auth0" % "java-jwt" % "4.4.0"

conflictManager := ConflictManager.latestCompatible

inThisBuild(
List(
semanticdbEnabled := true,
semanticdbVersion := scalafixSemanticdb.revision,
scalafixDependencies += "io.github.dedis" %% "scapegoat-scalafix" % "1.0" // Import custom rules
)
)
32 changes: 18 additions & 14 deletions be2-scala/linter/build.sbt
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
lazy val V = _root_.scalafix.sbt.BuildInfo
lazy val rulesCrossVersions = Seq(V.scala213, V.scala212)
lazy val rulesCrossVersions = Seq(V.scala213)
lazy val scala3Version = "3.3.1"

inThisBuild(
List(
organization := "dedis",
organization := "io.github.dedis",
organizationName := "dedis",
organizationHomepage := Some(url("https://dedis.epfl.ch")),
homepage := Some(url("https://github.com/dedis/popstellar")),
licenses := List("AGPL 3.0" -> url("https://www.gnu.org/licenses/agpl-3.0.en.html")),
developers := List(Developer("t1b00", "Thibault Czarniak", "[email protected]", url("https://www.linkedin.com/in/thcz/"))),
semanticdbEnabled := true,
semanticdbVersion := scalafixSemanticdb.revision
semanticdbVersion := scalafixSemanticdb.revision,
scmInfo := Some(ScmInfo(url("https://github.com/dedis/popstellar"), "scm:git@github:dedis/popstellar.git")),
version := "1.0",
versionScheme := Some("pvp"),
)
)

Expand All @@ -20,14 +28,13 @@ lazy val `popstellar` = (project in file("."))
.settings(
publish / skip := true
)

lazy val rules = projectMatrix
.settings(
moduleName := "scalafix",
libraryDependencies += "ch.epfl.scala" %% "scalafix-core" % V.scalafixVersion
moduleName := "scapegoat-scalafix",
libraryDependencies += "ch.epfl.scala" % "scalafix-core_2.13" % V.scalafixVersion,
)
.defaultAxes(VirtualAxis.jvm)
.jvmPlatform(rulesCrossVersions)
.jvmPlatform(rulesCrossVersions :+ scala3Version)

lazy val input = projectMatrix
.settings(
Expand All @@ -52,6 +59,7 @@ lazy val testsAggregate = Project("tests", file("target/testsAggregate"))
lazy val tests = projectMatrix
.settings(
publish / skip := true,
scalaVersion := V.scala213,
scalafixTestkitOutputSourceDirectories :=
TargetAxis
.resolve(output, Compile / unmanagedSourceDirectories)
Expand All @@ -70,20 +78,16 @@ lazy val tests = projectMatrix
.defaultAxes(
rulesCrossVersions.map(VirtualAxis.scalaABIVersion) :+ VirtualAxis.jvm: _*
)
.jvmPlatform(
scalaVersions = Seq(V.scala212),
axisValues = Seq(TargetAxis(scala3Version)),
settings = Seq()
)
.jvmPlatform(
scalaVersions = Seq(V.scala213),
axisValues = Seq(TargetAxis(V.scala213)),
settings = Seq()
)
.jvmPlatform(
scalaVersions = Seq(V.scala212),
axisValues = Seq(TargetAxis(V.scala212)),
scalaVersions = Seq(V.scala213),
axisValues = Seq(TargetAxis(scala3Version)),
settings = Seq()
)

.dependsOn(rules)
.enablePlugins(ScalafixTestkitPlugin)
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ object ArraysInFormat {
Array passed to format / interpolate string
*/

String.format("Here are my cool elements %d", Array.empty[Int]) // assert: ArraysInFormat

"Here are my cool elements %d".format(13) // scalafix: ok;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ object EmptyInterpolatedString {
val str = "I'm hungry!"
str.format() // assert: EmptyInterpolatedString
"I'm hungry!".format() // assert: EmptyInterpolatedString
"Test %s".format("test") // scalafix: ok;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ object IllegalFormatString {
val illegalFormatString1 = "%s is %d years old, %d"
String.format(illegalFormatString1, name, age) // assert: IllegalFormatString

String.format("%d is %d years old", age, name) // assert: IllegalFormatString

illegalFormatString1.format(name, age) // assert: IllegalFormatString

"%s is %d years old, %d".format(name, age) // assert: IllegalFormatString
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ package fix
object StripMarginOnRegex {
def test() = {
val regex = "match|this".stripMargin.r // assert: StripMarginOnRegex
val myRegex = "match|this"
myRegex.stripMargin.r // assert: StripMarginOnRegex
"match|that".stripMargin.r // assert: StripMarginOnRegex
"match_this".stripMargin.r // scalafix: ok;
"match|this".r // scalafix: ok;
Expand Down
3 changes: 2 additions & 1 deletion be2-scala/linter/project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
resolvers += Resolver.sonatypeRepo("releases")
addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.12.0")
addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.12.1")
addSbtPlugin("com.eed3si9n" % "sbt-projectmatrix" % "0.9.2")
addSbtPlugin("com.geirsson" % "sbt-ci-release" % "1.5.7")
t1b00 marked this conversation as resolved.
Show resolved Hide resolved
Loading
Loading