diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f0a1d2d..9c56b03 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -53,18 +53,19 @@ jobs: restore-keys: | ${{ runner.os }}-node_modules-cache-v2- + - name: Extract Tag Name + run: echo "TAG_NAME=$(echo ${GITHUB_REF##*/})" >> $GITHUB_ENV + if: ${{ startsWith(github.ref, 'refs/tags') }} + - name: Run tests run: | - sbt ";project scommons-admin-server ;set test in Test := {} ;project scommons-admin" coverage test sbt "project scommons-admin-server" coverage test it:test + sbt ";project scommons-admin-server ;set Test / test := {} ;project scommons-admin" coverage test sbt coverageAggregate coveralls + if: ${{ env.TAG_NAME == '' }} env: COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }} - - name: Extract Tag Name - run: echo "TAG_NAME=$(echo ${GITHUB_REF##*/})" >> $GITHUB_ENV - if: ${{ startsWith(github.ref, 'refs/tags') }} - - name: Publish SNAPSHOT run: echo "TODO - Publish latest version" @@ -74,7 +75,7 @@ jobs: run: | VERSION="$(echo "$TAG_NAME" | cut -d'v' -f 2)" echo "Publish a release version=$VERSION for tag $TAG_NAME" - version=$VERSION sbt clean "project scommons-admin-server" docker:publishLocal + version=$VERSION sbt clean ";set Global / scalaJSStage := FullOptStage ;project scommons-admin-server" docker:publishLocal docker tag scommons-admin-server:$VERSION scommons/admin:$VERSION docker tag scommons/admin:$VERSION scommons/admin:latest docker login -u $DOCKER_HUB_USER -p $DOCKER_HUB_TOKEN diff --git a/README.md b/README.md index 4c71e1b..b808231 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ [![CI](https://github.com/scommons/scommons-admin/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/scommons/scommons-admin/actions/workflows/ci.yml?query=workflow%3Aci+branch%3Amaster) [![Coverage Status](https://coveralls.io/repos/github/scommons/scommons-admin/badge.svg?branch=master)](https://coveralls.io/github/scommons/scommons-admin?branch=master) -[![Scala.js](https://www.scala-js.org/assets/badges/scalajs-1.1.0.svg)](https://www.scala-js.org) +[![Scala.js](https://www.scala-js.org/assets/badges/scalajs-1.5.0.svg)](https://www.scala-js.org) [![Docker image](https://img.shields.io/docker/v/scommons/admin?label=docker%20image&sort=date)](https://hub.docker.com/r/scommons/admin) # scommons-admin @@ -29,9 +29,9 @@ docker run -d --name scommons-admin -p 9000:9000 \ ## How to Build and Run locally -To build and run tests use the following command: +To build and run ALL tests use the following command: ```bash -sbt -mem 2048 test it:test +sbt -mem 2048 clean "project scommons-admin-server" test it:test && sbt -mem 2048 ";project scommons-admin-server ;set Test / test := {} ;project scommons-admin" test ``` #### How to Run Server locally in DEV mode @@ -40,7 +40,7 @@ Before you can run server, please, make sure you have PostgreSQL DB up and runni To start the application server locally in development mode with refresh workflow: ```bash -sbt -mem 2048 ';project scommons-admin-server ;set WebKeys.exportedMappings in Assets := Seq()' run +sbt -mem 2048 clean ';project scommons-admin-server ;set Assets / WebKeys.exportedMappings := Seq()' run ``` ## Admin Client UI diff --git a/client/src/main/scala/scommons/admin/client/user/UserDetailsTab.scala b/client/src/main/scala/scommons/admin/client/user/UserDetailsTab.scala index d43b9cd..6203287 100644 --- a/client/src/main/scala/scommons/admin/client/user/UserDetailsTab.scala +++ b/client/src/main/scala/scommons/admin/client/user/UserDetailsTab.scala @@ -2,7 +2,9 @@ package scommons.admin.client.user import scala.collection.mutable -class UserDetailsTab private(val id: String) extends AnyVal { +sealed abstract class UserDetailsTab private(val id: String) { + + UserDetailsTab.values += id -> this override def toString: String = id } @@ -13,12 +15,6 @@ object UserDetailsTab { def of(id: String): Option[UserDetailsTab] = values.get(id) - def apply(id: String): UserDetailsTab = { - val tab = new UserDetailsTab(id) - UserDetailsTab.values += id -> tab - tab - } - - val apps = UserDetailsTab("apps") - val profile = UserDetailsTab("profile") + case object apps extends UserDetailsTab("apps") + case object profile extends UserDetailsTab("profile") } diff --git a/client/src/main/scala/scommons/admin/client/user/UserProfilePanel.scala b/client/src/main/scala/scommons/admin/client/user/UserProfilePanel.scala index 6513592..fa2cf81 100644 --- a/client/src/main/scala/scommons/admin/client/user/UserProfilePanel.scala +++ b/client/src/main/scala/scommons/admin/client/user/UserProfilePanel.scala @@ -8,6 +8,11 @@ case class UserProfilePanelProps(data: UserProfileData) object UserProfilePanel extends FunctionComponent[UserProfilePanelProps] { + private[user] var firstNameComp: UiComponent[TextFieldProps] = TextField + private[user] var lastNameComp: UiComponent[TextFieldProps] = TextField + private[user] var emailComp: UiComponent[TextFieldProps] = TextField + private[user] var phoneComp: UiComponent[TextFieldProps] = TextField + override protected def create(): ReactClass = { ReactMemo[Props](super.create(), { (prevProps, nextProps) => prevProps.wrapped == nextProps.wrapped @@ -22,7 +27,7 @@ object UserProfilePanel extends FunctionComponent[UserProfilePanelProps] { <.div(^.className := "control-group")( <.label(^.className := "control-label")("First Name"), <.div(^.className := "controls")( - <(TextField())(^.wrapped := TextFieldProps( + <(firstNameComp())(^.wrapped := TextFieldProps( text = props.data.firstName, onChange = onChange, readOnly = true @@ -32,7 +37,7 @@ object UserProfilePanel extends FunctionComponent[UserProfilePanelProps] { <.div(^.className := "control-group")( <.label(^.className := "control-label")("Last Name"), <.div(^.className := "controls")( - <(TextField())(^.wrapped := TextFieldProps( + <(lastNameComp())(^.wrapped := TextFieldProps( text = props.data.lastName, onChange = onChange, readOnly = true @@ -42,7 +47,7 @@ object UserProfilePanel extends FunctionComponent[UserProfilePanelProps] { <.div(^.className := "control-group")( <.label(^.className := "control-label")("E-mail"), <.div(^.className := "controls")( - <(TextField())(^.wrapped := TextFieldProps( + <(emailComp())(^.wrapped := TextFieldProps( text = props.data.email, onChange = onChange, readOnly = true @@ -52,7 +57,7 @@ object UserProfilePanel extends FunctionComponent[UserProfilePanelProps] { <.div(^.className := "control-group")( <.label(^.className := "control-label")("Phone"), <.div(^.className := "controls")( - <(TextField())(^.wrapped := TextFieldProps( + <(phoneComp())(^.wrapped := TextFieldProps( text = props.data.phone.getOrElse(""), onChange = onChange, readOnly = true diff --git a/client/src/test/scala/scommons/admin/client/user/UserDetailsPanelSpec.scala b/client/src/test/scala/scommons/admin/client/user/UserDetailsPanelSpec.scala index 35c7842..6b73784 100644 --- a/client/src/test/scala/scommons/admin/client/user/UserDetailsPanelSpec.scala +++ b/client/src/test/scala/scommons/admin/client/user/UserDetailsPanelSpec.scala @@ -92,7 +92,7 @@ class UserDetailsPanelSpec extends TestSpec with TestRendererUtils { } } - assertTestComponent(result, tabPanelComp) { + assertTestComponent(result, tabPanelComp)(inside(_) { case TabPanelProps(List(systemsItem, profileItem), selectedIndex, _, direction) => selectedIndex shouldBe props.selectedTab.map { case UserDetailsTab.`apps` => 0 @@ -115,6 +115,6 @@ class UserDetailsPanelSpec extends TestSpec with TestRendererUtils { assertUserProfilePanel(render.get.apply(null), props.profile) } - } + }) } } diff --git a/client/src/test/scala/scommons/admin/client/user/UserEditPanelSpec.scala b/client/src/test/scala/scommons/admin/client/user/UserEditPanelSpec.scala index d1d0f52..01a5b3e 100644 --- a/client/src/test/scala/scommons/admin/client/user/UserEditPanelSpec.scala +++ b/client/src/test/scala/scommons/admin/client/user/UserEditPanelSpec.scala @@ -283,116 +283,106 @@ class UserEditPanelSpec extends TestSpec with TestRendererUtils { private def assertUserEditPanel(result: TestInstance, props: UserEditPanelProps): Unit = { val data = props.initialData - assertNativeComponent(result, <.div(^.className := "form-horizontal")(), { - case List( - loginComp, - passwordComp, - companyComp, - firstNameComp, - lastNameComp, - emailComp, - phoneComp, - noteComp - ) => - assertNativeComponent(loginComp, <.div(^.className := "control-group")(), inside(_) { case List(labelComp, controls) => - assertNativeComponent(labelComp, <.label(^.className := "control-label")("*Login")) - assertNativeComponent(controls, <.div(^.className := "controls")(), inside(_) { case List(fieldComp) => - assertTestComponent(fieldComp, textFieldComp) { - case TextFieldProps(text, _, requestFocus, requestSelect, className, placeholder, _, readOnly) => - text shouldBe data.user.login - requestFocus shouldBe props.requestFocus - requestSelect shouldBe props.requestFocus - className shouldBe None - placeholder shouldBe None - readOnly shouldBe false - } - }) - }) - assertNativeComponent(passwordComp, <.div(^.className := "control-group")(), inside(_) { case List(labelComp, controls) => - assertNativeComponent(labelComp, <.label(^.className := "control-label")("*Password")) - assertNativeComponent(controls, <.div(^.className := "controls")(), inside(_) { case List(fieldComp) => - assertTestComponent(fieldComp, passwordFieldComp) { - case PasswordFieldProps(password, _, requestFocus, requestSelect, className, placeholder, _, readOnly) => - password shouldBe data.user.password - requestFocus shouldBe false - requestSelect shouldBe false - className shouldBe None - placeholder shouldBe None - readOnly shouldBe false - } - }) - }) - assertNativeComponent(companyComp, <.div(^.className := "control-group")(), inside(_) { case List(labelComp, controls) => - assertNativeComponent(labelComp, <.label(^.className := "control-label")("*Company")) - assertNativeComponent(controls, <.div(^.className := "controls")(), inside(_) { case List(fieldComp) => - assertTestComponent(fieldComp, searchSelectComp) { - case SearchSelectProps(selected, _, _, isClearable, readOnly) => - selected shouldBe { - if (data.user.company.id == -1) None - else Some(SelectData(data.user.company.id.toString, data.user.company.name)) - } - isClearable shouldBe false - readOnly shouldBe false - } - }) - }) - assertNativeComponent(firstNameComp, <.div(^.className := "control-group")(), inside(_) { case List(labelComp, controls) => - assertNativeComponent(labelComp, <.label(^.className := "control-label")("*First Name")) - assertNativeComponent(controls, <.div(^.className := "controls")(), inside(_) { case List(fieldComp) => - assertTestComponent(fieldComp, textFieldComp) { - case TextFieldProps(text, _, requestFocus, requestSelect, className, placeholder, _, readOnly) => - text shouldBe data.profile.firstName - requestFocus shouldBe false - requestSelect shouldBe false - className shouldBe None - placeholder shouldBe None - readOnly shouldBe false - } - }) - }) - assertNativeComponent(lastNameComp, <.div(^.className := "control-group")(), inside(_) { case List(labelComp, controls) => - assertNativeComponent(labelComp, <.label(^.className := "control-label")("*Last Name")) - assertNativeComponent(controls, <.div(^.className := "controls")(), inside(_) { case List(fieldComp) => - assertTestComponent(fieldComp, textFieldComp) { - case TextFieldProps(text, _, requestFocus, requestSelect, className, placeholder, _, readOnly) => - text shouldBe data.profile.lastName - requestFocus shouldBe false - requestSelect shouldBe false - className shouldBe None - placeholder shouldBe None - readOnly shouldBe false - } - }) - }) - assertNativeComponent(emailComp, <.div(^.className := "control-group")(), inside(_) { case List(labelComp, controls) => - assertNativeComponent(labelComp, <.label(^.className := "control-label")("*E-mail")) - assertNativeComponent(controls, <.div(^.className := "controls")(), inside(_) { case List(fieldComp) => - assertTestComponent(fieldComp, textFieldComp) { - case TextFieldProps(text, _, requestFocus, requestSelect, className, placeholder, _, readOnly) => - text shouldBe data.profile.email - requestFocus shouldBe false - requestSelect shouldBe false - className shouldBe None - placeholder shouldBe None - readOnly shouldBe false - } - }) - }) - assertNativeComponent(phoneComp, <.div(^.className := "control-group")(), inside(_) { case List(labelComp, controls) => - assertNativeComponent(labelComp, <.label(^.className := "control-label")("Phone")) - assertNativeComponent(controls, <.div(^.className := "controls")(), inside(_) { case List(fieldComp) => - assertTestComponent(fieldComp, textFieldComp) { - case TextFieldProps(text, _, requestFocus, requestSelect, className, placeholder, _, readOnly) => - text shouldBe data.profile.phone.getOrElse("") - requestFocus shouldBe false - requestSelect shouldBe false - className shouldBe None - placeholder shouldBe None - readOnly shouldBe false - } - }) - }) - assertNativeComponent(noteComp, <.p()(<.small()("(*) Indicates required fields"))) - }) + assertNativeComponent(result, <.div(^.className := "form-horizontal")( + <.div(^.className := "control-group")( + <.label(^.className := "control-label")("*Login"), + <.div(^.className := "controls")( + <(textFieldComp())(^.assertWrapped(inside(_) { + case TextFieldProps(text, _, requestFocus, requestSelect, className, placeholder, _, readOnly) => + text shouldBe data.user.login + requestFocus shouldBe props.requestFocus + requestSelect shouldBe props.requestFocus + className shouldBe None + placeholder shouldBe None + readOnly shouldBe false + }))() + ) + ), + <.div(^.className := "control-group")( + <.label(^.className := "control-label")("*Password"), + <.div(^.className := "controls")( + <(passwordFieldComp())(^.assertWrapped(inside(_) { + case PasswordFieldProps(password, _, requestFocus, requestSelect, className, placeholder, _, readOnly) => + password shouldBe data.user.password + requestFocus shouldBe false + requestSelect shouldBe false + className shouldBe None + placeholder shouldBe None + readOnly shouldBe false + }))() + ) + ), + <.div(^.className := "control-group")( + <.label(^.className := "control-label")("*Company"), + <.div(^.className := "controls")( + <(searchSelectComp())(^.assertWrapped(inside(_) { + case SearchSelectProps(selected, _, _, isClearable, readOnly) => + selected shouldBe { + if (data.user.company.id == -1) None + else Some(SelectData(data.user.company.id.toString, data.user.company.name)) + } + isClearable shouldBe false + readOnly shouldBe false + }))() + ) + ), + <.div(^.className := "control-group")( + <.label(^.className := "control-label")("*First Name"), + <.div(^.className := "controls")( + <(textFieldComp())(^.assertWrapped(inside(_) { + case TextFieldProps(text, _, requestFocus, requestSelect, className, placeholder, _, readOnly) => + text shouldBe data.profile.firstName + requestFocus shouldBe false + requestSelect shouldBe false + className shouldBe None + placeholder shouldBe None + readOnly shouldBe false + }))() + ) + ), + <.div(^.className := "control-group")( + <.label(^.className := "control-label")("*Last Name"), + <.div(^.className := "controls")( + <(textFieldComp())(^.assertWrapped(inside(_) { + case TextFieldProps(text, _, requestFocus, requestSelect, className, placeholder, _, readOnly) => + text shouldBe data.profile.lastName + requestFocus shouldBe false + requestSelect shouldBe false + className shouldBe None + placeholder shouldBe None + readOnly shouldBe false + }))() + ) + ), + <.div(^.className := "control-group")( + <.label(^.className := "control-label")("*E-mail"), + <.div(^.className := "controls")( + <(textFieldComp())(^.assertWrapped(inside(_) { + case TextFieldProps(text, _, requestFocus, requestSelect, className, placeholder, _, readOnly) => + text shouldBe data.profile.email + requestFocus shouldBe false + requestSelect shouldBe false + className shouldBe None + placeholder shouldBe None + readOnly shouldBe false + }))() + ) + ), + <.div(^.className := "control-group")( + <.label(^.className := "control-label")("Phone"), + <.div(^.className := "controls")( + <(textFieldComp())(^.assertWrapped(inside(_) { + case TextFieldProps(text, _, requestFocus, requestSelect, className, placeholder, _, readOnly) => + text shouldBe data.profile.phone.getOrElse("") + requestFocus shouldBe false + requestSelect shouldBe false + className shouldBe None + placeholder shouldBe None + readOnly shouldBe false + }))() + ) + ), + <.p()(<.small()("(*) Indicates required fields")) + )) } } diff --git a/client/src/test/scala/scommons/admin/client/user/UserProfilePanelSpec.scala b/client/src/test/scala/scommons/admin/client/user/UserProfilePanelSpec.scala index 0ea4d97..c71feb8 100644 --- a/client/src/test/scala/scommons/admin/client/user/UserProfilePanelSpec.scala +++ b/client/src/test/scala/scommons/admin/client/user/UserProfilePanelSpec.scala @@ -1,12 +1,16 @@ package scommons.admin.client.user import scommons.admin.client.api.user._ -import scommons.client.ui.{TextField, TextFieldProps} -import scommons.react.test.TestSpec -import scommons.react.test.raw.TestInstance -import scommons.react.test.util.TestRendererUtils +import scommons.admin.client.user.UserProfilePanel._ +import scommons.client.ui.TextFieldProps +import scommons.react.test._ class UserProfilePanelSpec extends TestSpec with TestRendererUtils { + + UserProfilePanel.firstNameComp = mockUiComponent("firstNameComp") + UserProfilePanel.lastNameComp = mockUiComponent("lastNameComp") + UserProfilePanel.emailComp = mockUiComponent("emailComp") + UserProfilePanel.phoneComp = mockUiComponent("phoneComp") it should "render component" in { //given @@ -25,69 +29,63 @@ class UserProfilePanelSpec extends TestSpec with TestRendererUtils { } private def assertUserProfilePanel(result: TestInstance, props: UserProfilePanelProps): Unit = { - assertNativeComponent(result, <.div(^.className := "form-horizontal")(), { - case List( - firstNameComp, - lastNameComp, - emailComp, - phoneComp - ) => - assertNativeComponent(firstNameComp, <.div(^.className := "control-group")(), { case List(labelComp, controls) => - assertNativeComponent(labelComp, <.label(^.className := "control-label")("First Name")) - assertNativeComponent(controls, <.div(^.className := "controls")(), { case List(fieldComp) => - assertTestComponent(fieldComp, TextField) { - case TextFieldProps(text, _, requestFocus, requestSelect, className, placeholder, _, readOnly) => - text shouldBe props.data.firstName - requestFocus shouldBe false - requestSelect shouldBe false - className shouldBe None - placeholder shouldBe None - readOnly shouldBe true - } - }) - }) - assertNativeComponent(lastNameComp, <.div(^.className := "control-group")(), { case List(labelComp, controls) => - assertNativeComponent(labelComp, <.label(^.className := "control-label")("Last Name")) - assertNativeComponent(controls, <.div(^.className := "controls")(), { case List(fieldComp) => - assertTestComponent(fieldComp, TextField) { - case TextFieldProps(text, _, requestFocus, requestSelect, className, placeholder, _, readOnly) => - text shouldBe props.data.lastName - requestFocus shouldBe false - requestSelect shouldBe false - className shouldBe None - placeholder shouldBe None - readOnly shouldBe true - } - }) - }) - assertNativeComponent(emailComp, <.div(^.className := "control-group")(), { case List(labelComp, controls) => - assertNativeComponent(labelComp, <.label(^.className := "control-label")("E-mail")) - assertNativeComponent(controls, <.div(^.className := "controls")(), { case List(fieldComp) => - assertTestComponent(fieldComp, TextField) { - case TextFieldProps(text, _, requestFocus, requestSelect, className, placeholder, _, readOnly) => - text shouldBe props.data.email - requestFocus shouldBe false - requestSelect shouldBe false - className shouldBe None - placeholder shouldBe None - readOnly shouldBe true - } - }) - }) - assertNativeComponent(phoneComp, <.div(^.className := "control-group")(), { case List(labelComp, controls) => - assertNativeComponent(labelComp, <.label(^.className := "control-label")("Phone")) - assertNativeComponent(controls, <.div(^.className := "controls")(), { case List(fieldComp) => - assertTestComponent(fieldComp, TextField) { - case TextFieldProps(text, _, requestFocus, requestSelect, className, placeholder, _, readOnly) => - text shouldBe props.data.phone.getOrElse("") - requestFocus shouldBe false - requestSelect shouldBe false - className shouldBe None - placeholder shouldBe None - readOnly shouldBe true - } - }) - }) - }) + assertNativeComponent(result, <.div(^.className := "form-horizontal")( + <.div(^.className := "control-group")( + <.label(^.className := "control-label")("First Name"), + <.div(^.className := "controls")( + <(firstNameComp())(^.assertWrapped(inside(_) { + case TextFieldProps(text, _, requestFocus, requestSelect, className, placeholder, _, readOnly) => + text shouldBe props.data.firstName + requestFocus shouldBe false + requestSelect shouldBe false + className shouldBe None + placeholder shouldBe None + readOnly shouldBe true + }))() + ) + ), + <.div(^.className := "control-group")( + <.label(^.className := "control-label")("Last Name"), + <.div(^.className := "controls")( + <(lastNameComp())(^.assertWrapped(inside(_) { + case TextFieldProps(text, _, requestFocus, requestSelect, className, placeholder, _, readOnly) => + text shouldBe props.data.lastName + requestFocus shouldBe false + requestSelect shouldBe false + className shouldBe None + placeholder shouldBe None + readOnly shouldBe true + }))() + ) + ), + <.div(^.className := "control-group")( + <.label(^.className := "control-label")("E-mail"), + <.div(^.className := "controls")( + <(emailComp())(^.assertWrapped(inside(_) { + case TextFieldProps(text, _, requestFocus, requestSelect, className, placeholder, _, readOnly) => + text shouldBe props.data.email + requestFocus shouldBe false + requestSelect shouldBe false + className shouldBe None + placeholder shouldBe None + readOnly shouldBe true + }))() + ) + ), + <.div(^.className := "control-group")( + <.label(^.className := "control-label")("Phone"), + <.div(^.className := "controls")( + <(phoneComp())(^.assertWrapped(inside(_) { + case TextFieldProps(text, _, requestFocus, requestSelect, className, placeholder, _, readOnly) => + text shouldBe props.data.phone.getOrElse("") + requestFocus shouldBe false + requestSelect shouldBe false + className shouldBe None + placeholder shouldBe None + readOnly shouldBe true + }))() + ) + ) + )) } } diff --git a/project/build.properties b/project/build.properties index 40d3e51..83be3cf 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version = 1.3.8 \ No newline at end of file +sbt.version = 1.5.2 \ No newline at end of file diff --git a/project/plugins.sbt b/project/plugins.sbt index dbbe628..d14118f 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -4,7 +4,9 @@ resolvers += "Sonatype Snapshots" at "https://oss.sonatype.org/content/repositor //addSbtPlugin(("org.scommons.sbt" % "sbt-scommons-plugin" % "0.8.0-SNAPSHOT").changing()) addSbtPlugin("org.scommons.sbt" % "sbt-scommons-plugin" % "0.8.0") -addSbtPlugin("ch.epfl.scala" % "sbt-web-scalajs-bundler" % "0.18.0") +addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.5.1") +addSbtPlugin("ch.epfl.scala" % "sbt-scalajs-bundler" % "0.20.0") +addSbtPlugin("ch.epfl.scala" % "sbt-web-scalajs-bundler" % "0.20.0") // play plugin version should be the same as in `common.Libs.playVer` !!! addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.8.8") @@ -16,5 +18,5 @@ addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.3.3") addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.9.5") addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.1.0") -addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.6.1") +addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.7.3") addSbtPlugin("org.scoverage" % "sbt-coveralls" % "1.2.7") diff --git a/project/src/main/scala/common/CommonPlayModule.scala b/project/src/main/scala/common/CommonPlayModule.scala index 803a28d..6b17bc8 100644 --- a/project/src/main/scala/common/CommonPlayModule.scala +++ b/project/src/main/scala/common/CommonPlayModule.scala @@ -3,6 +3,7 @@ package common import com.typesafe.sbt.digest.Import.digest import com.typesafe.sbt.gzip.Import.gzip import com.typesafe.sbt.web.SbtWeb.autoImport._ +import org.scalajs.sbtplugin.ScalaJSPlugin.autoImport._ import play.sbt.routes.RoutesKeys import play.sbt.{PlayImport, PlayLayoutPlugin, PlayScala} import sbt._ @@ -29,10 +30,10 @@ trait CommonPlayModule extends CommonModule { RoutesKeys.routesImport -= "controllers.Assets.Asset", //remove unused import warning from routes file coverageExcludedPackages := ";Reverse.*;router.*", - pipelineStages in Assets := Seq(scalaJSPipeline), + Assets / pipelineStages := Seq(scalaJSPipeline), pipelineStages := Seq(digest, gzip), - devCommands in scalaJSPipeline ++= Seq("test", "testOnly") + Compile / fullOptJS / scalaJSLinkerConfig ~= (_.withSourceMap(false)) ) } diff --git a/project/src/main/scala/definitions/AdminServer.scala b/project/src/main/scala/definitions/AdminServer.scala index 45d81ae..d76bfdc 100644 --- a/project/src/main/scala/definitions/AdminServer.scala +++ b/project/src/main/scala/definitions/AdminServer.scala @@ -26,13 +26,13 @@ object AdminServer extends AdminModule with CommonPlayModule { .settings( scalaJSProjects := Seq(AdminClient.definition), - mainClass in Compile := Some("play.core.server.ProdServerStart"), + Compile / mainClass := Some("play.core.server.ProdServerStart"), dockerExposedPorts := port, - //dockerImageCreationTask := (publishLocal in Docker).value, + //dockerImageCreationTask := (Docker / publishLocal).value, dockerBaseImage := "openjdk:9-slim", - mappings in (Compile, packageDoc) := Seq(), - publishArtifact in (Compile, packageDoc) := false, + Compile / packageDoc / mappings := Seq(), + Compile / packageDoc / publishArtifact := false, dockerCommands := { val commands = dockerCommands.value diff --git a/project/src/main/scala/definitions/ScalaJsModule.scala b/project/src/main/scala/definitions/ScalaJsModule.scala index 7e8d98a..aa9d6e8 100644 --- a/project/src/main/scala/definitions/ScalaJsModule.scala +++ b/project/src/main/scala/definitions/ScalaJsModule.scala @@ -4,7 +4,6 @@ import org.scalajs.jsenv.nodejs.NodeJSEnv import org.scalajs.sbtplugin.ScalaJSPlugin.autoImport._ import sbt.Keys._ import sbt._ -import scoverage.ScoverageKeys.{coverageEnabled, coverageScalacPluginVersion} object ScalaJsModule { @@ -12,30 +11,11 @@ object ScalaJsModule { // required for node.js >= v12.12.0 // see: // https://github.com/nodejs/node/pull/29919 - jsEnv in Test := new NodeJSEnv(NodeJSEnv.Config().withArgs(List("--enable-source-maps"))), - scalaJSLinkerConfig in Test ~= { + Test / jsEnv := new NodeJSEnv(NodeJSEnv.Config().withArgs(List("--enable-source-maps"))), + Test / scalaJSLinkerConfig ~= { _.withSourceMap(true) }, - //TODO: remove these temporal fixes for Scala.js 1.1+ and scoverage - coverageScalacPluginVersion := { - val current = coverageScalacPluginVersion.value - if (scalaJSVersion.startsWith("0.6")) current - else "1.4.2" //the only version that supports Scala.js 1.1+ - }, - libraryDependencies ~= { modules => - if (scalaJSVersion.startsWith("0.6")) modules - else modules.filter(_.organization != "org.scoverage") - }, - libraryDependencies ++= { - if (coverageEnabled.value) { - if (scalaJSVersion.startsWith("0.6")) Nil - else Seq( - "org.scoverage" %% "scalac-scoverage-runtime_sjs1" % coverageScalacPluginVersion.value, - "org.scoverage" %% "scalac-scoverage-plugin" % coverageScalacPluginVersion.value % "scoveragePlugin" - ) - } - else Nil - } + scalaVersion := "2.13.5" ) } diff --git a/version.sbt b/version.sbt index e29d6d7..38e12e7 100644 --- a/version.sbt +++ b/version.sbt @@ -1 +1 @@ -version in ThisBuild := sys.env.getOrElse("version", default = "1.0.0-SNAPSHOT").stripPrefix("v") +ThisBuild / version := sys.env.getOrElse("version", default = "1.0.0-SNAPSHOT").stripPrefix("v")