From 584e61fdb0f82906aeb4df1de9009d2ce168f3c6 Mon Sep 17 00:00:00 2001 From: Rohan Sircar Date: Mon, 19 Apr 2021 16:05:48 +0530 Subject: [PATCH] Add linters and update ci file --- .github/workflows/ci.yaml | 31 +++++-- .scalafix.conf | 1 + build.sbt | 87 +++++++++++++++---- .../main/scala/wow/doge}/MonixBioSuite.scala | 2 +- project/plugins.sbt | 9 +- .../wow/doge/http4sdemo/MonixBioSuite.scala | 35 -------- src/main/resources/application.conf | 67 +++++--------- .../scala/wow/doge/http4sdemo/Migrate.scala | 1 + .../http4sdemo/LibraryControllerSpec.scala | 1 + 9 files changed, 127 insertions(+), 107 deletions(-) create mode 100644 .scalafix.conf rename {src/test/scala/wow/doge/http4sdemo => modules/test-common/src/main/scala/wow/doge}/MonixBioSuite.scala (96%) delete mode 100644 src/it/scala/wow/doge/http4sdemo/MonixBioSuite.scala diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 11b7158..72802f7 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -2,16 +2,34 @@ name: Continuous Integration on: pull_request: branches: ["*", series/*] + paths-ignore: + - ".dockerignore" + - ".github/workflow/ci.yml" + - "Changelog.md" + - "Dockerfile" + - "doc/**" + - "docker/**" + - "LICENSE" + - "README.md" + # - "tests/e2e/**" push: branches: ["*", series/*] tags: [v*] + paths-ignore: + - ".dockerignore" + - ".github/workflow/ci.yml" + - "Changelog.md" + - "Dockerfile" + - "doc/**" + - "docker/**" + - "LICENSE" + - "README.md" + # - "tests/e2e/**" jobs: - # Label of the container job build: name: Build and Test runs-on: ubuntu-latest - # container: node:12-buster env: CODEGEN_DB_HOST: localhost CODEGEN_DB_PORT: 5432 @@ -46,19 +64,21 @@ jobs: - name: Migrate run: csbt flyway/flywayMigrate - name: Lint - run: csbt scalafmtCheckAll + run: csbt "scalafmtCheckAll;scalafixAll --check" - name: Compile run: | csbt "compile; test:compile" - - name: Run Tests + - name: Run Unit Tests run: | csbt test + - name: Run Integration Tests + run: | + csbt it:test publish: name: Publish Release Docker Image needs: [build] if: github.event_name != 'pull_request' && startsWith(github.ref, 'refs/tags/v') runs-on: ubuntu-latest - # container: node:12-buster env: CODEGEN_DB_HOST: localhost CODEGEN_DB_PORT: 5432 @@ -106,7 +126,6 @@ jobs: needs: [build] if: github.event_name != 'pull_request' && github.ref == 'refs/heads/devel' runs-on: ubuntu-latest - # container: node:12-buster env: CODEGEN_DB_HOST: localhost CODEGEN_DB_PORT: 5432 diff --git a/.scalafix.conf b/.scalafix.conf new file mode 100644 index 0000000..114158f --- /dev/null +++ b/.scalafix.conf @@ -0,0 +1 @@ +rules = [OrganizeImports] \ No newline at end of file diff --git a/build.sbt b/build.sbt index 3976e6f..9d0829e 100644 --- a/build.sbt +++ b/build.sbt @@ -6,7 +6,7 @@ val MunitCatsEffectVersion = "0.13.0" val FlywayVersion = "7.5.3" scalaVersion in ThisBuild := "2.13.4" -resolvers += "jitpack" at "https://jitpack.io" +resolvers in ThisBuild += "jitpack" at "https://jitpack.io" import com.github.tototoshi.sbt.slick.CodegenPlugin.autoImport.{ slickCodegenDatabasePassword, @@ -14,8 +14,8 @@ import com.github.tototoshi.sbt.slick.CodegenPlugin.autoImport.{ slickCodegenJdbcDriver } -import _root_.slick.codegen.SourceCodeGenerator -import _root_.slick.{model => m} +import slick.codegen.SourceCodeGenerator +import slick.{model => m} lazy val codegenDbHost = sys.env.getOrElse("CODEGEN_DB_HOST", "localhost") lazy val codegenDbPort = sys.env.getOrElse("CODEGEN_DB_PORT", "5432") @@ -42,24 +42,39 @@ lazy val flyway = (project in file("modules/flyway")) flywayBaselineOnMigrate := true ) +lazy val testCommon = (project in file("modules/test-common")) + .settings( + libraryDependencies ++= Seq( + "com.github.monix" % "monix-bio" % "0a2ad29275", + "com.github.valskalla" %% "odin-monix" % "0.9.1", + "de.lolhens" %% "munit-tagless-final" % "0.0.1" + ) + ) + lazy val root = (project in file(".")) - .enablePlugins(CodegenPlugin, DockerPlugin, JavaAppPackaging, AshScriptPlugin) + .enablePlugins( + CodegenPlugin, + DockerPlugin, + JavaAppPackaging, + AshScriptPlugin, + BuildInfoPlugin, + GitBranchPrompt + ) .configs(IntegrationTest) .settings( organization := "wow.doge", name := "http4s-demo", - // version := releaseVersion.getOrElse(dynver.value), version in Docker := sys.env - .getOrElse( - "DOCKER_PUBLISH_TAG", { - val s = version.value - if (s.startsWith("v")) s.tail else s - } - ), + .get("DOCKER_PUBLISH_TAG") + .map(s => if (s.startsWith("v")) s.tail else s) + .getOrElse(version.value), dockerBaseImage := dockerJavaImage, dockerExposedPorts := Seq(8081), dockerUsername := Some("rohansircar"), Defaults.itSettings, + inConfig(IntegrationTest)(scalafixConfigSettings(IntegrationTest)), + buildInfoOptions ++= Seq(BuildInfoOption.ToJson, BuildInfoOption.BuildTime), + buildInfoPackage := "wow.doge.http4sdemo", scalacOptions ++= Seq( "-encoding", "UTF-8", @@ -77,8 +92,16 @@ lazy val root = (project in file(".")) "-Wconf:cat=lint-byname-implicit:s", //give errors on non exhaustive matches "-Wconf:msg=match may not be exhaustive:e", + // """-Wconf:site=wow\.doge\.http4sdemo\.slickcodegen\Tables\$:i""", + "-Wconf:msg=early initializers are deprecated:i", + """-Wconf:site=wow\.doge\.http4sdemo\.slickcodegen\..*:i""", + // """-Wconf:src=target/src_managed/Tables.scala:s""", "-explaintypes" // Explain type errors in more detail. ), + scalacOptions ++= { + if (insideCI.value) Seq("-Xfatal-warnings") + else Seq.empty + }, javacOptions ++= Seq("-source", "11", "-target", "11"), //format: off libraryDependencies ++= Seq( @@ -134,9 +157,14 @@ lazy val root = (project in file(".")) "com.dimafeng" %% "testcontainers-scala-munit" % "0.39.3" % IntegrationTest, "com.dimafeng" %% "testcontainers-scala-postgresql" % "0.39.3" % IntegrationTest ), - addCompilerPlugin("org.typelevel" %% "kind-projector" % "0.10.3"), - addCompilerPlugin("com.olegpy" %% "better-monadic-for" % "0.3.1"), - testFrameworks += new TestFramework("munit.Framework") + testFrameworks += new TestFramework("munit.Framework"), + buildInfoKeys := Seq[BuildInfoKey]( + name, + version, + scalaVersion, + sbtVersion, + libraryDependencies + ) ) .settings( slickCodegenDatabaseUrl := databaseUrl, @@ -149,6 +177,9 @@ lazy val root = (project in file(".")) slickCodegenCodeGenerator := { (model: m.Model) => new SourceCodeGenerator(model) { override def Table = new Table(_) { + // override def EntityType = new EntityType { + // override def caseClassFinal = true + // } override def Column = new Column(_) { override def rawType = model.tpe match { case "java.sql.Timestamp" => @@ -162,13 +193,37 @@ lazy val root = (project in file(".")) }, sourceGenerators in Compile += slickCodegen.taskValue ) - .dependsOn(flyway) + .dependsOn(flyway, testCommon) ThisBuild / scalafixDependencies += "com.github.liancheng" %% "organize-imports" % "0.4.3" inThisBuild( List( scalaVersion := scalaVersion.value, // 2.11.12, or 2.13.3 semanticdbEnabled := true, // enable SemanticDB - semanticdbVersion := "4.4.2" // use Scalafix compatible version + semanticdbVersion := "4.4.2", // use Scalafix compatible version + addCompilerPlugin("org.typelevel" %% "kind-projector" % "0.10.3"), + addCompilerPlugin("com.olegpy" %% "better-monadic-for" % "0.3.1") ) ) + +wartremoverErrors in (Compile, compile) ++= + Warts.allBut( + Wart.Any, + Wart.NonUnitStatements, + Wart.StringPlusAny, + Wart.Overloading, + Wart.PublicInference, + Wart.Nothing, + Wart.Var, + Wart.DefaultArguments, + Wart.OptionPartial, + // Wart.MutableDataStructures, + Wart.ImplicitConversion, + Wart.ImplicitParameter, + Wart.ToString, + Wart.Recursion, + Wart.While, + Wart.ExplicitImplicitTypes, + Wart.ListUnapply + ) +wartremoverExcluded += (sourceManaged in Compile).value diff --git a/src/test/scala/wow/doge/http4sdemo/MonixBioSuite.scala b/modules/test-common/src/main/scala/wow/doge/MonixBioSuite.scala similarity index 96% rename from src/test/scala/wow/doge/http4sdemo/MonixBioSuite.scala rename to modules/test-common/src/main/scala/wow/doge/MonixBioSuite.scala index a510219..eacb7b4 100644 --- a/src/test/scala/wow/doge/http4sdemo/MonixBioSuite.scala +++ b/modules/test-common/src/main/scala/wow/doge/MonixBioSuite.scala @@ -27,7 +27,7 @@ trait MonixBioSuite extends munit.TaglessFinalSuite[Task] { ( options: TestOptions, value: Logger[Task] - ) => Task(options.name), + ) => Task.unit, (_: Logger[Task]) => Task.unit ) diff --git a/project/plugins.sbt b/project/plugins.sbt index 8f9eb49..cc758f1 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,16 +1,15 @@ // addSbtPlugin("io.github.davidgregory084" % "sbt-tpolecat" % "0.1.14") -addSbtPlugin("io.spray" % "sbt-revolver" % "0.9.1") -// https://github.com/tototoshi/sbt-slick-codegen libraryDependencies += "com.h2database" % "h2" % "1.4.196" libraryDependencies += "org.postgresql" % "postgresql" % "42.2.18" +addSbtPlugin("io.spray" % "sbt-revolver" % "0.9.1") addSbtPlugin("com.github.tototoshi" % "sbt-slick-codegen" % "1.4.0") -// Database migration -// https://github.com/flyway/flyway-sbt addSbtPlugin("io.github.davidmweber" % "flyway-sbt" % "7.4.0") addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.9.23") addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.8.0") - addSbtPlugin("com.dwijnand" % "sbt-dynver" % "4.1.1") addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.2") +addSbtPlugin("com.typesafe.sbt" % "sbt-git" % "1.0.0") +addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.10.0") +addSbtPlugin("org.wartremover" % "sbt-wartremover" % "2.4.13") diff --git a/src/it/scala/wow/doge/http4sdemo/MonixBioSuite.scala b/src/it/scala/wow/doge/http4sdemo/MonixBioSuite.scala deleted file mode 100644 index f071539..0000000 --- a/src/it/scala/wow/doge/http4sdemo/MonixBioSuite.scala +++ /dev/null @@ -1,35 +0,0 @@ -package wow.doge.http4sdemo - -import cats.syntax.all._ -import io.odin.consoleLogger -import io.odin.fileLogger -import io.odin.syntax._ -import monix.bio.Task -import monix.execution.Scheduler - -import scala.concurrent.Future -import munit.TestOptions -import cats.effect.Resource -import io.odin.Logger - -trait MonixBioSuite extends munit.TaglessFinalSuite[Task] { - override protected def toFuture[A](f: Task[A]): Future[A] = { - implicit val s = Scheduler.global - f.runToFuture - } - - def loggerFixture(fileName: Option[String] = None)(implicit - enc: sourcecode.Enclosing - ) = - ResourceFixture( - consoleLogger[Task]().withAsync() |+| fileLogger[Task]( - fileName.getOrElse(enc.value.split("#").head + ".log") - ), - ( - options: TestOptions, - value: Logger[Task] - ) => Task(options.name), - (_: Logger[Task]) => Task.unit - ) - -} diff --git a/src/main/resources/application.conf b/src/main/resources/application.conf index c3f2231..f3f8d40 100644 --- a/src/main/resources/application.conf +++ b/src/main/resources/application.conf @@ -1,56 +1,35 @@ myapp = { database = { - driver = org.postgresql.Driver - # url = "jdbc:postgresql://localhost:5432/test_db" - dbHost = localhost - dbHost = ${?APP_DB_HOST} - dbPort = 5432 - dbPort = ${?APP_DB_PORT} - dbName = test_db - dbName = ${?APP_DB_NAME} - url = "jdbc:postgresql://"${myapp.database.dbHost}":"${myapp.database.dbPort}"/"${myapp.database.dbName} - user = "test_user" - password = "password" - - // The number of threads determines how many things you can *run* in parallel - // the number of connections determines you many things you can *keep in memory* at the same time - // on the database server. - // numThreads = (core_count (hyperthreading included)) - numThreads = 16 - - // queueSize = ((core_count * 2) + effective_spindle_count) - // on a MBP 13, this is 2 cores * 2 (hyperthreading not included) + 1 hard disk - queueSize = 1000 - - // https://blog.knoldus.com/2016/01/01/best-practices-for-using-slick-on-production/ - // make larger than numThreads + queueSize - maxConnections = 16 - - connectionTimeout = 5000 - validationTimeout = 5000 - - # connectionPool = disabled - keepAlive = true - - migrations-table = "flyway_schema_history" - + driver = org.postgresql.Driver + dbHost = localhost + dbHost = ${?APP_DB_HOST} + dbPort = 5432 + dbPort = ${?APP_DB_PORT} + dbName = test_db + dbName = ${?APP_DB_NAME} + url = "jdbc:postgresql://"${myapp.database.dbHost}":"${myapp.database.dbPort}"/"${myapp.database.dbName} + user = "test_user" + password = "password" + numThreads = 16 + queueSize = 1000 + maxConnections = 16 + connectionTimeout = 5000 + validationTimeout = 5000 + # connectionPool = disabled + keepAlive = true + migrations-table = "flyway_schema_history" migrations-locations = [ - # "classpath:example/jdbc" "classpath:db/migration/default" ] }, testDatabase = { - driver = org.postgresql.Driver - user = "scala" - password = "scala" - - numThreads = 16 - - queueSize = 10 - + driver = org.postgresql.Driver + user = "scala" + password = "scala" + numThreads = 16 + queueSize = 10 maxConnections = 36 - } } diff --git a/src/main/scala/wow/doge/http4sdemo/Migrate.scala b/src/main/scala/wow/doge/http4sdemo/Migrate.scala index b221a54..0101129 100644 --- a/src/main/scala/wow/doge/http4sdemo/Migrate.scala +++ b/src/main/scala/wow/doge/http4sdemo/Migrate.scala @@ -55,6 +55,7 @@ object DBMigrations extends LazyLogging { count } + @SuppressWarnings(Array("org.wartremover.warts.Null")) private def unsafeMigrate(config: JdbcDatabaseConfig): Int = { val m: FluentConfiguration = Flyway.configure .dataSource( diff --git a/src/test/scala/wow/doge/http4sdemo/LibraryControllerSpec.scala b/src/test/scala/wow/doge/http4sdemo/LibraryControllerSpec.scala index dc8946b..06b2167 100644 --- a/src/test/scala/wow/doge/http4sdemo/LibraryControllerSpec.scala +++ b/src/test/scala/wow/doge/http4sdemo/LibraryControllerSpec.scala @@ -11,6 +11,7 @@ import org.http4s.Method import org.http4s.Request import org.http4s.Uri import org.http4s.implicits._ +import wow.doge.http4sdemo.MonixBioSuite import wow.doge.http4sdemo.dto.Book import wow.doge.http4sdemo.dto.BookSearchMode import wow.doge.http4sdemo.dto.BookUpdate