From 4fc3d7306c00fc85716c476ced57bb5606c85924 Mon Sep 17 00:00:00 2001 From: sh0hei Date: Mon, 15 Feb 2021 16:19:43 +0900 Subject: [PATCH 1/2] Hello, scalafmt --- .scalafmt.conf | 18 ++++++ build.sbt | 24 +++++--- project/plugins.sbt | 1 + .../scala/sangria/marshalling/playJson.scala | 50 +++++++++------- .../marshalling/PlayJsonSupportSpec.scala | 60 ++++++++++--------- 5 files changed, 94 insertions(+), 59 deletions(-) create mode 100644 .scalafmt.conf diff --git a/.scalafmt.conf b/.scalafmt.conf new file mode 100644 index 0000000..c91d0d6 --- /dev/null +++ b/.scalafmt.conf @@ -0,0 +1,18 @@ +version = 2.7.5 + +style = default + +maxColumn = 100 + +// Vertical alignment is pretty, but leads to bigger diffs +align.preset = none + +danglingParentheses.preset = false + +rewrite.rules = [ + AvoidInfix + RedundantBraces + RedundantParens + AsciiSortImports + PreferCurlyFors +] diff --git a/build.sbt b/build.sbt index c49ec37..c209f92 100644 --- a/build.sbt +++ b/build.sbt @@ -4,7 +4,8 @@ mimaPreviousArtifacts := Set("org.sangria-graphql" %% "sangria-play-json" % "2.0 description := "Sangria play-json marshalling" homepage := Some(url("http://sangria-graphql.org")) -licenses := Seq("Apache License, ASL Version 2.0" -> url("http://www.apache.org/licenses/LICENSE-2.0")) +licenses := Seq( + "Apache License, ASL Version 2.0" -> url("http://www.apache.org/licenses/LICENSE-2.0")) ThisBuild / crossScalaVersions := Seq("2.12.13", "2.13.4") ThisBuild / scalaVersion := crossScalaVersions.value.last @@ -21,9 +22,9 @@ scalacOptions ++= Seq("-deprecation", "-feature") libraryDependencies ++= Seq( "org.sangria-graphql" %% "sangria-marshalling-api" % "1.0.5", "com.typesafe.play" %% "play-json" % "2.9.2", - "org.sangria-graphql" %% "sangria-marshalling-testkit" % "1.0.3" % Test, - "org.scalatest" %% "scalatest" % "3.2.3" % Test) + "org.scalatest" %% "scalatest" % "3.2.3" % Test +) // Publishing @@ -34,15 +35,20 @@ publishArtifact in Test := false pomIncludeRepository := (_ => false) publishTo := Some( if (version.value.trim.endsWith("SNAPSHOT")) - "snapshots" at "https://oss.sonatype.org/content/repositories/snapshots" + "snapshots".at("https://oss.sonatype.org/content/repositories/snapshots") else - "releases" at "https://oss.sonatype.org/service/local/staging/deploy/maven2") + "releases".at("https://oss.sonatype.org/service/local/staging/deploy/maven2")) startYear := Some(2016) organizationHomepage := Some(url("https://github.com/sangria-graphql")) -developers := Developer("OlegIlyenko", "Oleg Ilyenko", "", url("https://github.com/OlegIlyenko")) :: Nil -scmInfo := Some(ScmInfo( - browseUrl = url("https://github.com/sangria-graphql/sangria-play-json.git"), - connection = "scm:git:git@github.com:sangria-graphql/sangria-play-json.git")) +developers := Developer( + "OlegIlyenko", + "Oleg Ilyenko", + "", + url("https://github.com/OlegIlyenko")) :: Nil +scmInfo := Some( + ScmInfo( + browseUrl = url("https://github.com/sangria-graphql/sangria-play-json.git"), + connection = "scm:git:git@github.com:sangria-graphql/sangria-play-json.git")) // nice *magenta* prompt! diff --git a/project/plugins.sbt b/project/plugins.sbt index 3e1bd45..3c090f4 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -9,3 +9,4 @@ addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.8.1") addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.6.1") addSbtPlugin("org.scoverage" % "sbt-coveralls" % "1.2.7") addSbtPlugin("com.codecommit" % "sbt-github-actions" % "0.10.1") +addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.2") diff --git a/src/main/scala/sangria/marshalling/playJson.scala b/src/main/scala/sangria/marshalling/playJson.scala index 25dd933..1bdf08f 100644 --- a/src/main/scala/sangria/marshalling/playJson.scala +++ b/src/main/scala/sangria/marshalling/playJson.scala @@ -10,7 +10,11 @@ object playJson extends PlayJsonSupportLowPrioImplicits { type MapBuilder = ArrayMapBuilder[Node] override def emptyMapNode(keys: Seq[String]): MapBuilder = new ArrayMapBuilder[Node](keys) - override def addMapNodeElem(builder: MapBuilder, key: String, value: Node, optional: Boolean): MapBuilder = builder.add(key, value) + override def addMapNodeElem( + builder: MapBuilder, + key: String, + value: Node, + optional: Boolean): MapBuilder = builder.add(key, value) override def mapNode(builder: MapBuilder): Node = JsObject(builder.toSeq) override def mapNode(keyValues: Seq[(String, JsValue)]): Node = JsObject(keyValues) @@ -22,18 +26,19 @@ object playJson extends PlayJsonSupportLowPrioImplicits { case None => nullNode } - override def scalarNode(value: Any, typeName: String, info: Set[ScalarValueInfo]): Node = value match { - case v: String => JsString(v) - case true => JsTrue - case false => JsFalse - case v: Int => JsNumber(BigDecimal(v)) - case v: Long => JsNumber(BigDecimal(v)) - case v: Float => JsNumber(BigDecimal(v.toDouble)) - case v: Double => JsNumber(BigDecimal(v)) - case v: BigInt => JsNumber(BigDecimal(v)) - case v: BigDecimal => JsNumber(v) - case v => throw new IllegalArgumentException("Unsupported scalar value: " + v) - } + override def scalarNode(value: Any, typeName: String, info: Set[ScalarValueInfo]): Node = + value match { + case v: String => JsString(v) + case true => JsTrue + case false => JsFalse + case v: Int => JsNumber(BigDecimal(v)) + case v: Long => JsNumber(BigDecimal(v)) + case v: Float => JsNumber(BigDecimal(v.toDouble)) + case v: Double => JsNumber(BigDecimal(v)) + case v: BigInt => JsNumber(BigDecimal(v)) + case v: BigDecimal => JsNumber(v) + case v => throw new IllegalArgumentException("Unsupported scalar value: " + v) + } override def enumNode(value: String, typeName: String): Node = JsString(value) @@ -48,19 +53,21 @@ object playJson extends PlayJsonSupportLowPrioImplicits { } implicit object PlayJsonInputUnmarshaller extends InputUnmarshaller[JsValue] { - override def getRootMapValue(node: JsValue, key: String): Option[JsValue] = node.asInstanceOf[JsObject].value get key + override def getRootMapValue(node: JsValue, key: String): Option[JsValue] = + node.asInstanceOf[JsObject].value.get(key) override def isListNode(node: JsValue) = node.isInstanceOf[JsArray] override def getListValue(node: JsValue): Seq[JsValue] = node.asInstanceOf[JsArray].value.toSeq override def isMapNode(node: JsValue): Boolean = node.isInstanceOf[JsObject] - override def getMapValue(node: JsValue, key: String): Option[JsValue] = node.asInstanceOf[JsObject].value get key + override def getMapValue(node: JsValue, key: String): Option[JsValue] = + node.asInstanceOf[JsObject].value.get(key) override def getMapKeys(node: JsValue): Iterable[String] = node.asInstanceOf[JsObject].keys override def isDefined(node: JsValue): Boolean = node != JsNull override def getScalarValue(node: JsValue): Any = node match { case JsBoolean(b) => b - case JsNumber(d) => d.toBigIntExact getOrElse d + case JsNumber(d) => d.toBigIntExact.getOrElse(d) case JsString(s) => s case _ => throw new IllegalStateException(s"$node is not a scalar value") } @@ -75,7 +82,8 @@ object playJson extends PlayJsonSupportLowPrioImplicits { } override def isVariableNode(node: JsValue): Boolean = false - override def getVariableName(node: JsValue): String = throw new IllegalArgumentException("variables are not supported") + override def getVariableName(node: JsValue): String = throw new IllegalArgumentException( + "variables are not supported") override def render(node: JsValue): String = Json.stringify(node) } @@ -87,7 +95,7 @@ object playJson extends PlayJsonSupportLowPrioImplicits { implicit def playJsonToInput[T <: JsValue]: ToInput[T, JsValue] = PlayJsonToInput.asInstanceOf[ToInput[T, JsValue]] - implicit def playJsonWriterToInput[T : Writes]: ToInput[T, JsValue] = + implicit def playJsonWriterToInput[T: Writes]: ToInput[T, JsValue] = new ToInput[T, JsValue] { def toInput(value: T) = implicitly[Writes[T]].writes(value) -> PlayJsonInputUnmarshaller } @@ -100,14 +108,14 @@ object playJson extends PlayJsonSupportLowPrioImplicits { implicit def playJsonFromInput[T <: JsValue]: FromInput[T] = PlayJsonFromInput.asInstanceOf[FromInput[T]] - implicit def playJsonReaderFromInput[T : Reads]: FromInput[T] = + implicit def playJsonReaderFromInput[T: Reads]: FromInput[T] = new FromInput[T] { val marshaller = PlayJsonResultMarshaller def fromResult(node: marshaller.Node) = implicitly[Reads[T]].reads(node) match { case JsSuccess(v, _) => v case JsError(errors) => - val formattedErrors = errors.toVector.flatMap { - case (JsPath(nodes), es) => es.map(e => s"At path '${nodes mkString "."}': ${e.message}") + val formattedErrors = errors.toVector.flatMap { case (JsPath(nodes), es) => + es.map(e => s"At path '${nodes.mkString(".")}': ${e.message}") } throw InputParsingError(formattedErrors) diff --git a/src/test/scala/sangria/marshalling/PlayJsonSupportSpec.scala b/src/test/scala/sangria/marshalling/PlayJsonSupportSpec.scala index 3f2183f..31700ae 100644 --- a/src/test/scala/sangria/marshalling/PlayJsonSupportSpec.scala +++ b/src/test/scala/sangria/marshalling/PlayJsonSupportSpec.scala @@ -7,51 +7,54 @@ import sangria.marshalling.playJson._ import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec - -class PlayJsonSupportSpec extends AnyWordSpec with Matchers with MarshallingBehaviour with InputHandlingBehaviour with ParsingBehaviour { +class PlayJsonSupportSpec + extends AnyWordSpec + with Matchers + with MarshallingBehaviour + with InputHandlingBehaviour + with ParsingBehaviour { implicit val commentFormat = Json.format[Comment] implicit val articleFormat = Json.format[Article] "PlayJson integration" should { - behave like `value (un)marshaller` (PlayJsonResultMarshaller) - - behave like `AST-based input unmarshaller` (playJsonFromInput[JsValue]) - behave like `AST-based input marshaller` (PlayJsonResultMarshaller) - - behave like `case class input unmarshaller` - behave like `case class input marshaller` (PlayJsonResultMarshaller) - - behave like `input parser` (ParseTestSubjects( - complex = """{"a": [null, 123, [{"foo": "bar"}]], "b": {"c": true, "d": null}}""", - simpleString = "\"bar\"", - simpleInt = "12345", - simpleNull = "null", - list = "[\"bar\", 1, null, true, [1, 2, 3]]", - syntaxError = List("[123, \"FOO\" \"BAR\"") - )) + behave.like(`value (un)marshaller`(PlayJsonResultMarshaller)) + + behave.like(`AST-based input unmarshaller`(playJsonFromInput[JsValue])) + behave.like(`AST-based input marshaller`(PlayJsonResultMarshaller)) + + behave.like(`case class input unmarshaller`) + behave.like(`case class input marshaller`(PlayJsonResultMarshaller)) + + behave.like( + `input parser`(ParseTestSubjects( + complex = """{"a": [null, 123, [{"foo": "bar"}]], "b": {"c": true, "d": null}}""", + simpleString = "\"bar\"", + simpleInt = "12345", + simpleNull = "null", + list = "[\"bar\", 1, null, true, [1, 2, 3]]", + syntaxError = List("[123, \"FOO\" \"BAR\"") + ))) } val toRender = Json.obj( "a" -> Json.arr(JsNull, JsNumber(123), Json.arr(Json.obj("foo" -> JsString("bar")))), - "b" -> Json.obj( - "c" -> JsBoolean(true), - "d" -> JsNull)) + "b" -> Json.obj("c" -> JsBoolean(true), "d" -> JsNull)) "InputUnmarshaller" should { "throw an exception on invalid scalar values" in { - an [IllegalStateException] should be thrownBy - PlayJsonInputUnmarshaller.getScalarValue(Json.obj()) + an[IllegalStateException] should be thrownBy + PlayJsonInputUnmarshaller.getScalarValue(Json.obj()) } "throw an exception on variable names" in { - an [IllegalArgumentException] should be thrownBy - PlayJsonInputUnmarshaller.getVariableName(JsString("$foo")) + an[IllegalArgumentException] should be thrownBy + PlayJsonInputUnmarshaller.getVariableName(JsString("$foo")) } "render JSON values" in { val rendered = PlayJsonInputUnmarshaller.render(toRender) - rendered should be ("""{"a":[null,123,[{"foo":"bar"}]],"b":{"c":true,"d":null}}""") + rendered should be("""{"a":[null,123,[{"foo":"bar"}]],"b":{"c":true,"d":null}}""") } } @@ -59,8 +62,7 @@ class PlayJsonSupportSpec extends AnyWordSpec with Matchers with MarshallingBeha "render pretty JSON values" in { val rendered = PlayJsonResultMarshaller.renderPretty(toRender) - rendered.replaceAll("\r", "") should be ( - """{ + rendered.replaceAll("\r", "") should be("""{ | "a" : [ null, 123, [ { | "foo" : "bar" | } ] ], @@ -74,7 +76,7 @@ class PlayJsonSupportSpec extends AnyWordSpec with Matchers with MarshallingBeha "render compact JSON values" in { val rendered = PlayJsonResultMarshaller.renderCompact(toRender) - rendered should be ("""{"a":[null,123,[{"foo":"bar"}]],"b":{"c":true,"d":null}}""") + rendered should be("""{"a":[null,123,[{"foo":"bar"}]],"b":{"c":true,"d":null}}""") } } } From a2ee73e26fea1b8ab066a6859f0569c206112cc5 Mon Sep 17 00:00:00 2001 From: sh0hei Date: Tue, 16 Feb 2021 12:53:31 +0900 Subject: [PATCH 2/2] Add scalafmtCheckAll in CI --- .github/workflows/ci.yml | 3 +++ build.sbt | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e0c0741..7234b8e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -51,6 +51,9 @@ jobs: - name: Check binary compatibility run: sbt ++${{ matrix.scala }} mimaReportBinaryIssues + - name: Check formatting + run: sbt ++${{ matrix.scala }} scalafmtCheckAll + - name: Check that workflows are up to date run: sbt ++${{ matrix.scala }} githubWorkflowCheck diff --git a/build.sbt b/build.sbt index c209f92..f07d71c 100644 --- a/build.sbt +++ b/build.sbt @@ -11,7 +11,8 @@ ThisBuild / crossScalaVersions := Seq("2.12.13", "2.13.4") ThisBuild / scalaVersion := crossScalaVersions.value.last ThisBuild / githubWorkflowPublishTargetBranches := List() ThisBuild / githubWorkflowBuildPreamble ++= List( - WorkflowStep.Sbt(List("mimaReportBinaryIssues"), name = Some("Check binary compatibility")) + WorkflowStep.Sbt(List("mimaReportBinaryIssues"), name = Some("Check binary compatibility")), + WorkflowStep.Sbt(List("scalafmtCheckAll"), name = Some("Check formatting")) ) scalacOptions += "-target:jvm-1.8"