diff --git a/src/reference/00-Getting-Started/02-sbt-by-example.md b/src/reference/00-Getting-Started/02-sbt-by-example.md index 018823783..ff7d632af 100644 --- a/src/reference/00-Getting-Started/02-sbt-by-example.md +++ b/src/reference/00-Getting-Started/02-sbt-by-example.md @@ -26,11 +26,13 @@ Let's start with examples rather than explaining how sbt works or why. ``` \$ sbt -[info] Updated file /tmp/foo-build/project/build.properties: set sbt.version to 1.1.4 +[info] Updated file /tmp/foo-build/project/build.properties: set sbt.version to 1.9.3 +[info] welcome to sbt 1.9.3 (Eclipse Adoptium Java 17.0.8) [info] Loading project definition from /tmp/foo-build/project -[info] Loading settings from build.sbt ... +[info] loading settings for project foo-build from build.sbt ... [info] Set current project to foo-build (in build file:/tmp/foo-build/) [info] sbt server started at local:///Users/eed3si9n/.sbt/1.0/server/abc4fb6c89985a00fd95/sock +[info] started sbt server sbt:foo-build> ``` @@ -58,8 +60,9 @@ re-executed whenever one of the source files within the project is modified. For ``` sbt:foo-build> ~compile -[success] Total time: 0 s, completed May 6, 2018 3:52:08 PM -1. Waiting for source changes... (press enter to interrupt) +[success] Total time: 0 s, completed 28 Jul 2023, 13:32:35 +[info] 1. Monitoring source files for foo-build/compile... +[info] Press to interrupt or '?' for more options. ``` ### Create a source file @@ -81,10 +84,11 @@ object Hello { This new file should be picked up by the running command: ``` -[info] Compiling 1 Scala source to /tmp/foo-build/target/scala-2.12/classes ... -[info] Done compiling. -[success] Total time: 2 s, completed May 6, 2018 3:53:42 PM -2. Waiting for source changes... (press enter to interrupt) +[info] Build triggered by /tmp/foo-build/src/main/scala/example/Hello.scala. Running 'compile'. +[info] compiling 1 Scala source to /tmp/foo-build/target/scala-2.12/classes ... +[success] Total time: 0 s, completed 28 Jul 2023, 13:38:55 +[info] 2. Monitoring source files for foo-build/compile... +[info] Press to interrupt or '?' for more options. ``` Press `Enter` to exit `~compile`. @@ -105,13 +109,14 @@ Use the `help` command to get basic help about the available commands. ``` sbt:foo-build> help - about Displays basic information about sbt and the build. - tasks Lists the tasks defined for the current project. - settings Lists the settings defined for the current project. - reload (Re)loads the current project or changes to plugins project or returns from it. - new Creates a new sbt build. - projects Lists the names of available projects or temporarily adds/removes extra builds to the session. - project Displays the current project or changes to the provided `project`. + (; )* Runs the provided semicolon-separated commands. + about Displays basic information about sbt and the build. + tasks Lists the tasks defined for the current project. + settings Lists the settings defined for the current project. + reload (Re)loads the current project or changes to plugins project or returns from it. + new Creates a new sbt build. + new Creates a new sbt build. + projects Lists the names of available projects or temporarily adds/removes extra builds to the session. .... ``` @@ -127,11 +132,9 @@ Runs a main class, passing along arguments provided on the command line. ``` sbt:foo-build> run -[info] Packaging /tmp/foo-build/target/scala-2.12/foo-build_2.12-0.1.0-SNAPSHOT.jar ... -[info] Done packaging. -[info] Running example.Hello +[info] running example.Hello Hello -[success] Total time: 1 s, completed May 6, 2018 4:10:44 PM +[success] Total time: 0 s, completed 28 Jul 2023, 13:40:31 ``` ### Set ThisBuild / scalaVersion from sbt shell @@ -139,6 +142,10 @@ Hello ``` sbt:foo-build> set ThisBuild / scalaVersion := "$example_scala213$" [info] Defining ThisBuild / scalaVersion +[info] The new value will be used by Compile / bspBuildTarget, Compile / dependencyTreeCrossProjectId and 50 others. +[info] Run `last` for details. +[info] Reapplying settings... +[info] set current project to foo-build (in build file:/tmp/foo-build/) ``` Check the `scalaVersion` setting: @@ -155,6 +162,13 @@ We can save the ad-hoc settings using `session save`. ``` sbt:foo-build> session save [info] Reapplying settings... +[info] set current project to foo-build (in build file:/tmp/foo-build/) +[warn] build source files have changed +[warn] modified files: +[warn] /tmp/foo-build/build.sbt +[warn] Apply these changes by running `reload`. +[warn] Automatically reload the build when source changes are detected by setting `Global / onChangedBuildSource := ReloadOnSourceChanges`. +[warn] Disable this warning by setting `Global / onChangedBuildSource := IgnoreSourceChanges`. ``` `build.sbt` file should now contain: @@ -177,19 +191,20 @@ Use the `reload` command to reload the build. The command causes the ``` sbt:foo-build> reload -[info] Loading project definition from /tmp/foo-build/project -[info] Loading settings from build.sbt ... -[info] Set current project to Hello (in build file:/tmp/foo-build/) +[info] welcome to sbt 1.9.3 (Eclipse Adoptium Java 17.0.8) +[info] loading project definition from /tmp/foo-build/project +[info] loading settings for project hello from build.sbt ... +[info] set current project to Hello (in build file:/tmp/foo-build/) sbt:Hello> ``` Note that the prompt has now changed to `sbt:Hello>`. -### Add ScalaTest to libraryDependencies +### Add toolkit-test to libraryDependencies Using an editor, change `build.sbt` as follows: -@@snip [scalatest]($root$/src/sbt-test/ref/example-scalatest/build.sbt) {} +@@snip [example-test]($root$/src/sbt-test/ref/example-test/build.sbt) {} Use the `reload` command to reflect the change in `build.sbt`. @@ -211,37 +226,36 @@ sbt:Hello> ~testQuick ### Write a test -Leaving the previous command running, create a file named `src/test/scala/HelloSpec.scala` +Leaving the previous command running, create a file named `src/test/scala/example/HelloSuite.scala` using an editor: -@@snip [scalatest]($root$/src/sbt-test/ref/example-scalatest/src/test/scala/HelloSpec.scala) {} +@@snip [example-test]($root$/src/sbt-test/ref/example-test/src/test/scala/example/HelloSuite.scala) {} `~testQuick` should pick up the change: ``` -2. Waiting for source changes... (press enter to interrupt) -[info] Compiling 1 Scala source to /tmp/foo-build/target/scala-2.12/test-classes ... -[info] Done compiling. -[info] HelloSpec: -[info] - Hello should start with H *** FAILED *** -[info] assert("hello".startsWith("H")) -[info] | | | -[info] "hello" false "H" (HelloSpec.scala:5) -[info] Run completed in 135 milliseconds. -[info] Total number of tests run: 1 -[info] Suites: completed 1, aborted 0 -[info] Tests: succeeded 0, failed 1, canceled 0, ignored 0, pending 0 -[info] *** 1 TEST FAILED *** +[info] 2. Monitoring source files for hello/testQuick... +[info] Press to interrupt or '?' for more options. +[info] Build triggered by /tmp/foo-build/src/test/scala/example/HelloSuite.scala. Running 'testQuick'. +[info] compiling 1 Scala source to /tmp/foo-build/target/scala-2.13/test-classes ... +HelloSuite: +==> X HelloSuite.Hello should start with H 0.004s munit.FailException: /tmp/foo-build/src/test/scala/example/HelloSuite.scala:4 assertion failed +3: test("Hello should start with H") { +4: assert("hello".startsWith("H")) +5: } + at munit.FunSuite.assert(FunSuite.scala:11) + at HelloSuite.\$anonfun\$new\$1(HelloSuite.scala:4) +[error] Failed: Total 1, Failed 1, Errors 0, Passed 0 [error] Failed tests: -[error] HelloSpec +[error] HelloSuite [error] (Test / testQuick) sbt.TestsFailedException: Tests unsuccessful ``` ### Make the test pass -Using an editor, change `src/test/scala/HelloSpec.scala` to: +Using an editor, change `src/test/scala/example/HelloSuite.scala` to: -@@snip [scalatest]($root$/src/sbt-test/ref/example-scalatest/changes/HelloSpec.scala) {} +@@snip [example-test]($root$/src/sbt-test/ref/example-test/changes/HelloSuite.scala) {} Confirm that the test passes, then press `Enter` to exit the continuous test. @@ -260,60 +274,51 @@ We can find out the current weather in New York. ```scala sbt:Hello> console [info] Starting scala interpreter... -Welcome to Scala 2.12.7 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_171). +Welcome to Scala 2.13.11 (OpenJDK 64-Bit Server VM, Java 17). Type in expressions for evaluation. Or try :help. scala> :paste // Entering paste mode (ctrl-D to finish) -import scala.concurrent._, duration._ -import gigahorse._, support.okhttp.Gigahorse -import play.api.libs.json._ - -Gigahorse.withHttp(Gigahorse.config) { http => - val baseUrl = "https://www.metaweather.com/api/location" - val rLoc = Gigahorse.url(baseUrl + "/search/").get. - addQueryString("query" -> "New York") - val fLoc = http.run(rLoc, Gigahorse.asString) - val loc = Await.result(fLoc, 10.seconds) - val woeid = (Json.parse(loc) \\ 0 \\ "woeid").get - val rWeather = Gigahorse.url(baseUrl + s"/\$woeid/").get - val fWeather = http.run(rWeather, Gigahorse.asString) - val weather = Await.result(fWeather, 10.seconds) - ({Json.parse(_: String)} andThen Json.prettyPrint)(weather) -} +import sttp.client4.quick._ +import sttp.client4.Response + +val newYorkLatitude: Double = 40.7143 +val newYorkLongitude: Double = -74.006 +val response: Response[String] = quickRequest + .get( + uri"https://api.open-meteo.com/v1/forecast?latitude=\$newYorkLatitude&longitude=\$newYorkLongitude¤t_weather=true" + ) + .send() + +println(ujson.read(response.body).render(indent = 2)) // press Ctrl+D // Exiting paste mode, now interpreting. -import scala.concurrent._ -import duration._ -import gigahorse._ -import support.okhttp.Gigahorse -import play.api.libs.json._ -res0: String = { - "consolidated_weather" : [ { - "id" : 6446939314847744, - "weather_state_name" : "Light Rain", - "weather_state_abbr" : "lr", - "wind_direction_compass" : "WNW", - "created" : "2019-02-21T04:39:47.747805Z", - "applicable_date" : "2019-02-21", - "min_temp" : 0.48000000000000004, - "max_temp" : 7.84, - "the_temp" : 2.1700000000000004, - "wind_speed" : 5.996333145703094, - "wind_direction" : 293.12257757287307, - "air_pressure" : 1033.115, - "humidity" : 77, - "visibility" : 14.890539250775472, - "predictability" : 75 - }, { - "id" : 5806299509948416, - "weather_state_name" : "Heavy Cloud", -... + "latitude": 40.710335, + "longitude": -73.99307, + "generationtime_ms": 0.36704540252685547, + "utc_offset_seconds": 0, + "timezone": "GMT", + "timezone_abbreviation": "GMT", + "elevation": 51, + "current_weather": { + "temperature": 21.3, + "windspeed": 16.7, + "winddirection": 205, + "weathercode": 3, + "is_day": 1, + "time": "2023-08-04T10:00" + } +} +import sttp.client4.quick._ +import sttp.client4.Response +val newYorkLatitude: Double = 40.7143 +val newYorkLongitude: Double = -74.006 +val response: sttp.client4.Response[String] = Response({"latitude":40.710335,"longitude":-73.99307,"generationtime_ms":0.36704540252685547,"utc_offset_seconds":0,"timezone":"GMT","timezone_abbreviation":"GMT","elevation":51.0,"current_weather":{"temperature":21.3,"windspeed":16.7,"winddirection":205.0,"weathercode":3,"is_day":1,"time":"2023-08-04T10:00"}},200,,List(:status: 200, content-encoding: deflate, content-type: application/json; charset=utf-8, date: Fri, 04 Aug 2023 10:09:11 GMT),List(),RequestMetadata(GET,https://api.open-meteo.com/v1/forecast?latitude=40.7143&longitude... scala> :q // to quit ``` @@ -341,7 +346,7 @@ sbt:Hello> projects sbt:Hello> helloCore/compile ``` -### Add ScalaTest to the subproject +### Add toolkit-test to the subproject Change `build.sbt` as follows: @@ -367,9 +372,9 @@ Use `.dependsOn(...)` to add a dependency on other subprojects. Also let's move @@snip [example-sub4]($root$/src/sbt-test/ref/example-sub4/build.sbt) {} -### Parse JSON using Play JSON +### Parse JSON using uJson -Let's add Play JSON to `helloCore`. +Let's use uJson from the toolkit in `helloCore`. @@snip [example-weather-build]($root$/src/sbt-test/ref/example-weather/build.sbt) {} @@ -378,29 +383,19 @@ After `reload`, add `core/src/main/scala/example/core/Weather.scala`: ```scala package example.core -import gigahorse._, support.okhttp.Gigahorse -import scala.concurrent._, duration._ -import play.api.libs.json._ +import sttp.client4.quick._ +import sttp.client4.Response object Weather { - lazy val http = Gigahorse.http(Gigahorse.config) - - def weather: Future[String] = { - val baseUrl = "https://www.metaweather.com/api/location" - val locUrl = baseUrl + "/search/" - val weatherUrl = baseUrl + "/%s/" - val rLoc = Gigahorse.url(locUrl).get. - addQueryString("query" -> "New York") - import ExecutionContext.Implicits.global - for { - loc <- http.run(rLoc, parse) - woeid = (loc \\ 0 \\ "woeid").get - rWeather = Gigahorse.url(weatherUrl format woeid).get - weather <- http.run(rWeather, parse) - } yield (weather \\\\ "weather_state_name")(0).as[String].toLowerCase + def temp() = { + val response: Response[String] = quickRequest + .get( + uri"https://api.open-meteo.com/v1/forecast?latitude=40.7143&longitude=-74.006¤t_weather=true" + ) + .send() + val json = ujson.read(response.body) + json.obj("current_weather")("temperature").num } - - private def parse = Gigahorse.asString andThen Json.parse } ``` @@ -409,14 +404,12 @@ Next, change `src/main/scala/example/Hello.scala` as follows: ```scala package example -import scala.concurrent._, duration._ -import core.Weather +import example.core.Weather object Hello { def main(args: Array[String]): Unit = { - val w = Await.result(Weather.weather, 10.seconds) - println(s"Hello! The weather in New York is \$w.") - Weather.http.close() + val temp = Weather.temp() + println(s"Hello! The current temperature in New York is \$temp C.") } } ``` @@ -425,16 +418,10 @@ Let's run the app to see if it worked: ``` sbt:Hello> run -[info] Compiling 1 Scala source to /tmp/foo-build/core/target/scala-2.12/classes ... -[info] Done compiling. -[info] Compiling 1 Scala source to /tmp/foo-build/target/scala-2.12/classes ... -[info] Packaging /tmp/foo-build/core/target/scala-2.12/hello-core_2.12-0.1.0-SNAPSHOT.jar ... -[info] Done packaging. -[info] Done compiling. -[info] Packaging /tmp/foo-build/target/scala-2.12/hello_2.12-0.1.0-SNAPSHOT.jar ... -[info] Done packaging. -[info] Running example.Hello -Hello! The weather in New York is mostly cloudy. +[info] compiling 1 Scala source to /tmp/foo-build/core/target/scala-2.13/classes ... +[info] compiling 1 Scala source to /tmp/foo-build/target/scala-2.13/classes ... +[info] running example.Hello +Hello! The current temperature in New York is 22.7 C. ``` ### Add sbt-native-packager plugin @@ -453,8 +440,13 @@ Next change `build.sbt` as follows to add `JavaAppPackaging`: sbt:Hello> reload ... sbt:Hello> dist -[info] Wrote /tmp/foo-build/target/scala-2.12/hello_2.12-0.1.0-SNAPSHOT.pom -[info] Wrote /tmp/foo-build/core/target/scala-2.12/hello-core_2.12-0.1.0-SNAPSHOT.pom +[info] Wrote /private/tmp/foo-build/target/scala-2.13/hello_2.13-0.1.0-SNAPSHOT.pom +[info] Main Scala API documentation to /tmp/foo-build/target/scala-2.13/api... +[info] Main Scala API documentation successful. +[info] Main Scala API documentation to /tmp/foo-build/core/target/scala-2.13/api... +[info] Wrote /tmp/foo-build/core/target/scala-2.13/hello-core_2.13-0.1.0-SNAPSHOT.pom +[info] Main Scala API documentation successful. +[success] All package validations passed [info] Your package is ready in /tmp/foo-build/target/universal/hello-0.1.0-SNAPSHOT.zip ``` @@ -465,24 +457,24 @@ Here's how you can run the packaged app: \$ cd /tmp/someother \$ unzip -o -d /tmp/someother /tmp/foo-build/target/universal/hello-0.1.0-SNAPSHOT.zip \$ ./hello-0.1.0-SNAPSHOT/bin/hello -Hello! The weather in New York is mostly cloudy. +Hello! The current temperature in New York is 22.7 C. ``` ### Dockerize your app +_Note that a Docker daemon will need to be running in order for this to work._ + ``` sbt:Hello> Docker/publishLocal .... -[info] Successfully built b6ce1b6ab2c0 -[info] Successfully tagged hello:0.1.0-SNAPSHOT -[info] Built image hello:0.1.0-SNAPSHOT +[info] Built image hello with tags [0.1.0-SNAPSHOT] ``` Here's how to run the Dockerized app: ``` \$ docker run hello:0.1.0-SNAPSHOT -Hello! The weather in New York is mostly cloudy +Hello! The current temperature in New York is 22.7 C. ``` ### Set the version @@ -494,8 +486,8 @@ Change `build.sbt` as follows: ### Switch scalaVersion temporarily ``` -sbt:Hello> ++2.12.14! -[info] Forcing Scala version to 2.12.14 on all projects. +sbt:Hello> ++3.3.0! +[info] Forcing Scala version to 3.3.0 on all projects. [info] Reapplying settings... [info] Set current project to Hello (in build file:/tmp/foo-build/) ``` @@ -505,9 +497,9 @@ Check the `scalaVersion` setting: ``` sbt:Hello> scalaVersion [info] helloCore / scalaVersion -[info] 2.12.14 +[info] 3.3.0 [info] scalaVersion -[info] 2.12.14 +[info] 3.3.0 ``` This setting will go away after `reload`. @@ -536,7 +528,7 @@ sbt:Hello> inspect tree dist You can also run sbt in batch mode, passing sbt commands directly from the terminal. ``` -\$ sbt clean "testOnly HelloSpec" +\$ sbt clean "testOnly HelloSuite" ``` **Note**: Running in batch mode requires JVM spinup and JIT each time, diff --git a/src/reference/es/00-Getting-Started/02-sbt-by-example.md b/src/reference/es/00-Getting-Started/02-sbt-by-example.md index 7a3c5bf56..99719e02d 100644 --- a/src/reference/es/00-Getting-Started/02-sbt-by-example.md +++ b/src/reference/es/00-Getting-Started/02-sbt-by-example.md @@ -27,11 +27,13 @@ o por qué sbt funciona. ``` \$ sbt -[info] Updated file /tmp/foo-build/project/build.properties: set sbt.version to 1.1.4 +[info] Updated file /tmp/foo-build/project/build.properties: set sbt.version to 1.9.3 +[info] welcome to sbt 1.9.3 (Eclipse Adoptium Java 17.0.8) [info] Loading project definition from /tmp/foo-build/project -[info] Loading settings from build.sbt ... +[info] loading settings for project foo-build from build.sbt ... [info] Set current project to foo-build (in build file:/tmp/foo-build/) [info] sbt server started at local:///Users/eed3si9n/.sbt/1.0/server/abc4fb6c89985a00fd95/sock +[info] started sbt server sbt:foo-build> ``` @@ -62,8 +64,9 @@ fuente dentro del proyecto sea modificado. Por ejemplo: ``` sbt:foo-build> ~compile -[success] Total time: 0 s, completed May 6, 2018 3:52:08 PM -1. Waiting for source changes... (press enter to interrupt) +[success] Total time: 0 s, completed 28 Jul 2023, 13:32:35 +[info] 1. Monitoring source files for foo-build/compile... +[info] Press to interrupt or '?' for more options. ``` ### Crear un fichero fuente @@ -87,10 +90,11 @@ object Hello { Este nuevo fichero debería de ser detectado por el comando en ejecución: ``` -[info] Compiling 1 Scala source to /tmp/foo-build/target/scala-2.12/classes ... -[info] Done compiling. -[success] Total time: 2 s, completed May 6, 2018 3:53:42 PM -2. Waiting for source changes... (press enter to interrupt) +[info] Build triggered by /tmp/foo-build/src/main/scala/example/Hello.scala. Running 'compile'. +[info] compiling 1 Scala source to /tmp/foo-build/target/scala-2.12/classes ... +[success] Total time: 0 s, completed 28 Jul 2023, 13:38:55 +[info] 2. Monitoring source files for foo-build/compile... +[info] Press to interrupt or '?' for more options. ``` Pulsa `Intro` para salir de `~compile`. @@ -111,13 +115,14 @@ Usa el comando `help` para obtener ayuda básica sobre los comandos disponibles. ``` sbt:foo-build> help - about Displays basic information about sbt and the build. - tasks Lists the tasks defined for the current project. - settings Lists the settings defined for the current project. - reload (Re)loads the current project or changes to plugins project or returns from it. - new Creates a new sbt build. - projects Lists the names of available projects or temporarily adds/removes extra builds to the session. - project Displays the current project or changes to the provided `project`. + (; )* Runs the provided semicolon-separated commands. +about Displays basic information about sbt and the build. +tasks Lists the tasks defined for the current project. +settings Lists the settings defined for the current project. +reload (Re)loads the current project or changes to plugins project or returns from it. +new Creates a new sbt build. +new Creates a new sbt build. +projects Lists the names of available projects or temporarily adds/removes extra builds to the session. .... ``` @@ -133,11 +138,9 @@ Runs a main class, passing along arguments provided on the command line. ``` sbt:foo-build> run -[info] Packaging /tmp/foo-build/target/scala-2.12/foo-build_2.12-0.1.0-SNAPSHOT.jar ... -[info] Done packaging. -[info] Running example.Hello +[info] running example.Hello Hello -[success] Total time: 1 s, completed May 6, 2018 4:10:44 PM +[success] Total time: 0 s, completed 28 Jul 2023, 13:40:31 ``` ### Establecer `ThisBuild / scalaVersion` desde el shell de sbt @@ -145,6 +148,10 @@ Hello ``` sbt:foo-build> set ThisBuild / scalaVersion := "$example_scala213$" [info] Defining ThisBuild / scalaVersion +[info] The new value will be used by Compile / bspBuildTarget, Compile / dependencyTreeCrossProjectId and 50 others. +[info] Run `last` for details. +[info] Reapplying settings... +[info] set current project to foo-build (in build file:/tmp/foo-build/) ``` ### Comprobar la entrada `scalaVersion`: @@ -161,6 +168,13 @@ Podemos guardar la configuración temporal utilizando `session save`. ``` sbt:foo-build> session save [info] Reapplying settings... +[info] set current project to foo-build (in build file:/tmp/foo-build/) +[warn] build source files have changed +[warn] modified files: +[warn] /tmp/foo-build/build.sbt +[warn] Apply these changes by running `reload`. +[warn] Automatically reload the build when source changes are detected by setting `Global / onChangedBuildSource := ReloadOnSourceChanges`. +[warn] Disable this warning by setting `Global / onChangedBuildSource := IgnoreSourceChanges`. ``` El fichero `build.sbt` ahora debería de contener: @@ -183,19 +197,20 @@ aplicada. ``` sbt:foo-build> reload -[info] Loading project definition from /tmp/foo-build/project -[info] Loading settings from build.sbt ... -[info] Set current project to Hello (in build file:/tmp/foo-build/) +[info] welcome to sbt 1.9.3 (Eclipse Adoptium Java 17.0.8) +[info] loading project definition from /tmp/foo-build/project +[info] loading settings for project hello from build.sbt ... +[info] set current project to Hello (in build file:/tmp/foo-build/) sbt:Hello> ``` Fíjate en cómo el prompt ha cambiado a `sbt:Hello>`. -### Añadir ScalaTest a `libraryDependencies` +### Añadir toolkit-test a `libraryDependencies` Utilizando un editor, modifica `build.sbt` de la siguiente manera: -@@snip [scalatest]($root$/src/sbt-test/ref/example-scalatest/build.sbt) {} +@@snip [scalatest]($root$/src/sbt-test/ref/example-test/build.sbt) {} Usa el comando `reload` para reflejar los cambios de `build.sbt`. @@ -218,36 +233,35 @@ sbt:Hello> ~testQuick ### Escribir un test Con el comando anterior ejecutándose, crea un fichero llamado -`src/test/scala/HelloSpec.scala` utilizando un editor: +`src/test/scala/example/HelloSuite.scala` utilizando un editor: -@@snip [scalatest]($root$/src/sbt-test/ref/example-scalatest/src/test/scala/HelloSpec.scala) {} +@@snip [example-test]($root$/src/sbt-test/ref/example-test/src/test/scala/example/HelloSuite.scala) {} `~testQuick` debería de coger el cambio: ``` -2. Waiting for source changes... (press enter to interrupt) -[info] Compiling 1 Scala source to /tmp/foo-build/target/scala-2.12/test-classes ... -[info] Done compiling. -[info] HelloSpec: -[info] - Hello should start with H *** FAILED *** -[info] assert("hello".startsWith("H")) -[info] | | | -[info] "hello" false "H" (HelloSpec.scala:5) -[info] Run completed in 135 milliseconds. -[info] Total number of tests run: 1 -[info] Suites: completed 1, aborted 0 -[info] Tests: succeeded 0, failed 1, canceled 0, ignored 0, pending 0 -[info] *** 1 TEST FAILED *** +[info] 2. Monitoring source files for hello/testQuick... +[info] Press to interrupt or '?' for more options. +[info] Build triggered by /tmp/foo-build/src/test/scala/example/HelloSuite.scala. Running 'testQuick'. +[info] compiling 1 Scala source to /tmp/foo-build/target/scala-2.13/test-classes ... +HelloSuite: +==> X HelloSuite.Hello should start with H 0.004s munit.FailException: /tmp/foo-build/src/test/scala/example/HelloSuite.scala:4 assertion failed +3: test("Hello should start with H") { +4: assert("hello".startsWith("H")) +5: } +at munit.FunSuite.assert(FunSuite.scala:11) +at HelloSuite.\$anonfun\$new\$1(HelloSuite.scala:4) +[error] Failed: Total 1, Failed 1, Errors 0, Passed 0 [error] Failed tests: -[error] HelloSpec +[error] HelloSuite [error] (Test / testQuick) sbt.TestsFailedException: Tests unsuccessful ``` ### Hacer que el test pase -Utilizando un editor, cambia `src/test/scala/HelloSpec.scala` a: +Utilizando un editor, cambia `src/test/scala/example/HelloSuite.scala` a: -@@snip [scalatest]($root$/src/sbt-test/ref/example-scalatest/changes/HelloSpec.scala) {} +@@snip [scalatest]($root$/src/sbt-test/ref/example-test/changes/HelloSuite.scala) {} Confirma que el test pasa, luego pulsa `Intro` para salir del test continuo. @@ -263,65 +277,57 @@ Usa el comando `reload` para reflejar los cambios de `build.sbt`. Podemos averiguar qué tiempo hace actualmente en Nueva York. + ```scala sbt:Hello> console [info] Starting scala interpreter... -Welcome to Scala 2.12.7 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_171). +Welcome to Scala 2.13.11 (OpenJDK 64-Bit Server VM, Java 17). Type in expressions for evaluation. Or try :help. scala> :paste // Entering paste mode (ctrl-D to finish) -import scala.concurrent._, duration._ -import gigahorse._, support.okhttp.Gigahorse -import play.api.libs.json._ - -Gigahorse.withHttp(Gigahorse.config) { http => - val baseUrl = "https://www.metaweather.com/api/location" - val rLoc = Gigahorse.url(baseUrl + "/search/").get. - addQueryString("query" -> "New York") - val fLoc = http.run(rLoc, Gigahorse.asString) - val loc = Await.result(fLoc, 10.seconds) - val woeid = (Json.parse(loc) \\ 0 \\ "woeid").get - val rWeather = Gigahorse.url(baseUrl + s"/\$woeid/").get - val fWeather = http.run(rWeather, Gigahorse.asString) - val weather = Await.result(fWeather, 10.seconds) - ({Json.parse(_: String)} andThen Json.prettyPrint)(weather) -} +import sttp.client4.quick._ +import sttp.client4.Response + +val newYorkLatitude: Double = 40.7143 +val newYorkLongitude: Double = -74.006 +val response: Response[String] = quickRequest + .get( + uri"https://api.open-meteo.com/v1/forecast?latitude=\$newYorkLatitude&longitude=\$newYorkLongitude¤t_weather=true" + ) + .send() + +println(ujson.read(response.body).render(indent = 2)) // press Ctrl+D // Exiting paste mode, now interpreting. -import scala.concurrent._ -import duration._ -import gigahorse._ -import support.okhttp.Gigahorse -import play.api.libs.json._ -res0: String = { - "consolidated_weather" : [ { - "id" : 6446939314847744, - "weather_state_name" : "Light Rain", - "weather_state_abbr" : "lr", - "wind_direction_compass" : "WNW", - "created" : "2019-02-21T04:39:47.747805Z", - "applicable_date" : "2019-02-21", - "min_temp" : 0.48000000000000004, - "max_temp" : 7.84, - "the_temp" : 2.1700000000000004, - "wind_speed" : 5.996333145703094, - "wind_direction" : 293.12257757287307, - "air_pressure" : 1033.115, - "humidity" : 77, - "visibility" : 14.890539250775472, - "predictability" : 75 - }, { - "id" : 5806299509948416, - "weather_state_name" : "Heavy Cloud", -... + "latitude": 40.710335, + "longitude": -73.99307, + "generationtime_ms": 0.36704540252685547, + "utc_offset_seconds": 0, + "timezone": "GMT", + "timezone_abbreviation": "GMT", + "elevation": 51, + "current_weather": { + "temperature": 21.3, + "windspeed": 16.7, + "winddirection": 205, + "weathercode": 3, + "is_day": 1, + "time": "2023-08-04T10:00" + } +} +import sttp.client4.quick._ +import sttp.client4.Response +val newYorkLatitude: Double = 40.7143 +val newYorkLongitude: Double = -74.006 +val response: sttp.client4.Response[String] = Response({"latitude":40.710335,"longitude":-73.99307,"generationtime_ms":0.36704540252685547,"utc_offset_seconds":0,"timezone":"GMT","timezone_abbreviation":"GMT","elevation":51.0,"current_weather":{"temperature":21.3,"windspeed":16.7,"winddirection":205.0,"weathercode":3,"is_day":1,"time":"2023-08-04T10:00"}},200,,List(:status: 200, content-encoding: deflate, content-type: application/json; charset=utf-8, date: Fri, 04 Aug 2023 10:09:11 GMT),List(),RequestMetadata(GET,https://api.open-meteo.com/v1/forecast?latitude=40.7143&longitude... -scala> :q // para salir +scala> :q // to quit ``` ### Crear un subproyecto @@ -347,7 +353,7 @@ sbt:Hello> projects sbt:Hello> helloCore/compile ``` -### Añadir ScalaTest al subproyecto +### Añadir toolkit-test al subproyecto Cambia `build.sbt` como sigue: @@ -374,9 +380,9 @@ Además, movamos la dependencia de Gigahorse a `helloCore`. @@snip [example-sub4]($root$/src/sbt-test/ref/example-sub4/build.sbt) {} -### Parsear JSON con Play JSON +### Parsear JSON con uJson -Vamos a añadir Play JSON a `helloCore`. +Vamos a añadir uJson de toolkit a `helloCore`. @@snip [example-weather-build]($root$/src/sbt-test/ref/example-weather/build.sbt) {} @@ -385,46 +391,35 @@ Tras un `reload`, añade `core/src/main/scala/example/core/Weather.scala`: ```scala package example.core -import gigahorse._, support.okhttp.Gigahorse -import scala.concurrent._, duration._ -import play.api.libs.json._ +import sttp.client4.quick._ +import sttp.client4.Response object Weather { - lazy val http = Gigahorse.http(Gigahorse.config) - - def weather: Future[String] = { - val baseUrl = "https://www.metaweather.com/api/location" - val locUrl = baseUrl + "/search/" - val weatherUrl = baseUrl + "/%s/" - val rLoc = Gigahorse.url(locUrl).get. - addQueryString("query" -> "New York") - import ExecutionContext.Implicits.global - for { - loc <- http.run(rLoc, parse) - woeid = (loc \\ 0 \\ "woeid").get - rWeather = Gigahorse.url(weatherUrl format woeid).get - weather <- http.run(rWeather, parse) - } yield (weather \\\\ "weather_state_name")(0).as[String].toLowerCase - } - - private def parse = Gigahorse.asString andThen Json.parse + def temp() = { + val response: Response[String] = quickRequest + .get( + uri"https://api.open-meteo.com/v1/forecast?latitude=40.7143&longitude=-74.006¤t_weather=true" + ) + .send() + val json = ujson.read(response.body) + json.obj("current_weather")("temperature").num + } } ``` Ahora, cambia `src/main/scala/example/Hello.scala` como sigue: + ```scala package example -import scala.concurrent._, duration._ -import core.Weather +import example.core.Weather object Hello { - def main(args: Array[String]): Unit = { - val w = Await.result(Weather.weather, 10.seconds) - println(s"Hello! The weather in New York is \$w.") - Weather.http.close() - } + def main(args: Array[String]): Unit = { + val temp = Weather.temp() + println(s"Hello! The current temperature in New York is \$temp C.") + } } ``` @@ -432,16 +427,10 @@ Vamos a ejecutar la aplicación para ver si funciona: ``` sbt:Hello> run -[info] Compiling 1 Scala source to /tmp/foo-build/core/target/scala-2.12/classes ... -[info] Done compiling. -[info] Compiling 1 Scala source to /tmp/foo-build/target/scala-2.12/classes ... -[info] Packaging /tmp/foo-build/core/target/scala-2.12/hello-core_2.12-0.1.0-SNAPSHOT.jar ... -[info] Done packaging. -[info] Done compiling. -[info] Packaging /tmp/foo-build/target/scala-2.12/hello_2.12-0.1.0-SNAPSHOT.jar ... -[info] Done packaging. -[info] Running example.Hello -Hello! The weather in New York is mostly cloudy. +[info] compiling 1 Scala source to /tmp/foo-build/core/target/scala-2.13/classes ... +[info] compiling 1 Scala source to /tmp/foo-build/target/scala-2.13/classes ... +[info] running example.Hello +Hello! The current temperature in New York is 22.7 C. ``` ### Añadir el plugin sbt-native-packager @@ -456,12 +445,18 @@ Después cambia `build.sbt` como sigue para añadir `JavaAppPackaging`: ### Recargar y crear una distribución .zip + ``` sbt:Hello> reload ... sbt:Hello> dist -[info] Wrote /tmp/foo-build/target/scala-2.12/hello_2.12-0.1.0-SNAPSHOT.pom -[info] Wrote /tmp/foo-build/core/target/scala-2.12/hello-core_2.12-0.1.0-SNAPSHOT.pom +[info] Wrote /private/tmp/foo-build/target/scala-2.13/hello_2.13-0.1.0-SNAPSHOT.pom +[info] Main Scala API documentation to /tmp/foo-build/target/scala-2.13/api... +[info] Main Scala API documentation successful. +[info] Main Scala API documentation to /tmp/foo-build/core/target/scala-2.13/api... +[info] Wrote /tmp/foo-build/core/target/scala-2.13/hello-core_2.13-0.1.0-SNAPSHOT.pom +[info] Main Scala API documentation successful. +[success] All package validations passed [info] Your package is ready in /tmp/foo-build/target/universal/hello-0.1.0-SNAPSHOT.zip ``` @@ -472,7 +467,7 @@ Así es cómo puedes ejecutar la app una vez empaquetada: \$ cd /tmp/someother \$ unzip -o -d /tmp/someother /tmp/foo-build/target/universal/hello-0.1.0-SNAPSHOT.zip \$ ./hello-0.1.0-SNAPSHOT/bin/hello -Hello! The weather in New York is mostly cloudy. +Hello! The current temperature in New York is 22.7 C. ``` ### Dockerizar tu app @@ -480,16 +475,14 @@ Hello! The weather in New York is mostly cloudy. ``` sbt:Hello> Docker/publishLocal .... -[info] Successfully built b6ce1b6ab2c0 -[info] Successfully tagged hello:0.1.0-SNAPSHOT -[info] Built image hello:0.1.0-SNAPSHOT +[info] Built image hello with tags [0.1.0-SNAPSHOT] ``` Así es cómo puedes ejecutar la app Dockerizada: ``` \$ docker run hello:0.1.0-SNAPSHOT -Hello! The weather in New York is mostly cloudy +Hello! The current temperature in New York is 22.7 C. ``` ### Establecer la versión @@ -501,8 +494,8 @@ Cambia `build.sbt` como sigue: ### Cambiar `scalaVersion` temporalmente ``` -sbt:Hello> ++2.12.14! -[info] Forcing Scala version to 2.12.14 on all projects. +sbt:Hello> ++3.3.0! +[info] Forcing Scala version to 3.3.0 on all projects. [info] Reapplying settings... [info] Set current project to Hello (in build file:/tmp/foo-build/) ``` @@ -512,9 +505,9 @@ Comprueba la entrada `scalaVersion`: ``` sbt:Hello> scalaVersion [info] helloCore / scalaVersion -[info] 2.12.14 +[info] 3.3.0 [info] scalaVersion -[info] 2.12.14 +[info] 3.3.0 ``` Esta entrada se esfumará tras un `reload`. @@ -543,7 +536,7 @@ También puedes ejecutar sbt en por lotes, pasando comandos de sbt directamente desde el terminal. ``` -\$ sbt clean "testOnly HelloSpec" +\$ sbt clean "testOnly HelloSuite" ``` **Note**: El modo por lotes implica levantar una JVM y JIT cada vez, por lo que diff --git a/src/reference/ja/00-Getting-Started/02-sbt-by-example.md b/src/reference/ja/00-Getting-Started/02-sbt-by-example.md index 8cd12431d..68af6d6a6 100644 --- a/src/reference/ja/00-Getting-Started/02-sbt-by-example.md +++ b/src/reference/ja/00-Getting-Started/02-sbt-by-example.md @@ -27,11 +27,13 @@ sbt の内部がどうなっているかや理由みたいなことを解説す ``` \$ sbt -[info] Updated file /tmp/foo-build/project/build.properties: set sbt.version to 1.1.4 -[info] Loading project definition from /private/tmp/foo-build/project -[info] Loading settings from build.sbt ... -[info] Set current project to foo-build (in build file:/private/tmp/foo-build/) +[info] Updated file /tmp/foo-build/project/build.properties: set sbt.version to 1.9.3 +[info] welcome to sbt 1.9.3 (Eclipse Adoptium Java 17.0.8) +[info] Loading project definition from /tmp/foo-build/project +[info] loading settings for project foo-build from build.sbt ... +[info] Set current project to foo-build (in build file:/tmp/foo-build/) [info] sbt server started at local:///Users/eed3si9n/.sbt/1.0/server/abc4fb6c89985a00fd95/sock +[info] started sbt server sbt:foo-build> ``` @@ -58,8 +60,9 @@ sbt:foo-build> compile ``` sbt:foo-build> ~compile -[success] Total time: 0 s, completed May 6, 2018 3:52:08 PM -1. Waiting for source changes... (press enter to interrupt) +[success] Total time: 0 s, completed 28 Jul 2023, 13:32:35 +[info] 1. Monitoring source files for foo-build/compile... +[info] Press to interrupt or '?' for more options. ``` ### ソース・ファイルを書く @@ -79,10 +82,11 @@ object Hello { この新しいファイルは実行中のコマンドが自動的に検知したはずだ: ``` -[info] Compiling 1 Scala source to /private/tmp/foo-build/target/scala-2.12/classes ... -[info] Done compiling. -[success] Total time: 2 s, completed May 6, 2018 3:53:42 PM -2. Waiting for source changes... (press enter to interrupt) +[info] Build triggered by /tmp/foo-build/src/main/scala/example/Hello.scala. Running 'compile'. +[info] compiling 1 Scala source to /tmp/foo-build/target/scala-2.12/classes ... +[success] Total time: 0 s, completed 28 Jul 2023, 13:38:55 +[info] 2. Monitoring source files for foo-build/compile... +[info] Press to interrupt or '?' for more options. ``` `~compile` を抜けるには `Enter` を押す。 @@ -102,13 +106,14 @@ sbt:foo-build> compile ``` sbt:foo-build> help - about Displays basic information about sbt and the build. - tasks Lists the tasks defined for the current project. - settings Lists the settings defined for the current project. - reload (Re)loads the current project or changes to plugins project or returns from it. - new Creates a new sbt build. - projects Lists the names of available projects or temporarily adds/removes extra builds to the session. - project Displays the current project or changes to the provided `project`. + (; )* Runs the provided semicolon-separated commands. +about Displays basic information about sbt and the build. +tasks Lists the tasks defined for the current project. +settings Lists the settings defined for the current project. +reload (Re)loads the current project or changes to plugins project or returns from it. +new Creates a new sbt build. +new Creates a new sbt build. +projects Lists the names of available projects or temporarily adds/removes extra builds to the session. .... ``` @@ -124,11 +129,9 @@ Runs a main class, passing along arguments provided on the command line. ``` sbt:foo-build> run -[info] Packaging /private/tmp/foo-build/target/scala-2.12/foo-build_2.12-0.1.0-SNAPSHOT.jar ... -[info] Done packaging. -[info] Running example.Hello +[info] running example.Hello Hello -[success] Total time: 1 s, completed May 6, 2018 4:10:44 PM +[success] Total time: 0 s, completed 28 Jul 2023, 13:40:31 ``` ### sbt シェルから ThisBuild / scalaVersion をセットする @@ -136,6 +139,10 @@ Hello ``` sbt:foo-build> set ThisBuild / scalaVersion := "$example_scala213$" [info] Defining ThisBuild / scalaVersion +[info] The new value will be used by Compile / bspBuildTarget, Compile / dependencyTreeCrossProjectId and 50 others. +[info] Run `last` for details. +[info] Reapplying settings... +[info] set current project to foo-build (in build file:/tmp/foo-build/) ``` `scalaVersion` セッティングを確認する: @@ -152,6 +159,13 @@ sbt:foo-build> scalaVersion ``` sbt:foo-build> session save [info] Reapplying settings... +[info] set current project to foo-build (in build file:/tmp/foo-build/) +[warn] build source files have changed +[warn] modified files: +[warn] /tmp/foo-build/build.sbt +[warn] Apply these changes by running `reload`. +[warn] Automatically reload the build when source changes are detected by setting `Global / onChangedBuildSource := ReloadOnSourceChanges`. +[warn] Disable this warning by setting `Global / onChangedBuildSource := IgnoreSourceChanges`. ``` `build.sbt` ファイルは以下のようになったはずだ: @@ -172,19 +186,20 @@ ThisBuild / scalaVersion := "$example_scala213$" ``` sbt:foo-build> reload -[info] Loading project definition from /private/tmp/foo-build/project -[info] Loading settings from build.sbt ... -[info] Set current project to Hello (in build file:/private/tmp/foo-build/) +[info] welcome to sbt 1.9.3 (Eclipse Adoptium Java 17.0.8) +[info] loading project definition from /tmp/foo-build/project +[info] loading settings for project hello from build.sbt ... +[info] set current project to Hello (in build file:/tmp/foo-build/) sbt:Hello> ``` プロンプトが `sbt:Hello>` に変わったことに注目してほしい。 -### libraryDependencies に ScalaTest を追加する +### libraryDependencies に toolkit-test を追加する エディタを使って、`build.sbt` を以下のように変更する: -@@snip [scalatest]($root$/src/sbt-test/ref/example-scalatest/build.sbt) {} +@@snip [example-test]($root$/src/sbt-test/ref/example-test/build.sbt) {} `reload` コマンドを使って、`build.sbt` の変更を反映させる。 @@ -206,36 +221,35 @@ sbt:Hello> ~testQuick ### テストを書く -上のコマンドを走らせたままで、エディタから `src/test/scala/HelloSpec.scala` という名前のファイルを作成する: +上のコマンドを走らせたままで、エディタから `src/test/scala/example/HelloSuite.scala` という名前のファイルを作成する: -@@snip [scalatest]($root$/src/sbt-test/ref/example-scalatest/src/test/scala/HelloSpec.scala) {} +@@snip [example-test]($root$/src/sbt-test/ref/example-test/src/test/scala/example/HelloSuite.scala) {} `~testQuick` が検知したはずだ: ``` -2. Waiting for source changes... (press enter to interrupt) -[info] Compiling 1 Scala source to /private/tmp/foo-build/target/scala-2.12/test-classes ... -[info] Done compiling. -[info] HelloSpec: -[info] - Hello should start with H *** FAILED *** -[info] assert("hello".startsWith("H")) -[info] | | | -[info] "hello" false "H" (HelloSpec.scala:5) -[info] Run completed in 135 milliseconds. -[info] Total number of tests run: 1 -[info] Suites: completed 1, aborted 0 -[info] Tests: succeeded 0, failed 1, canceled 0, ignored 0, pending 0 -[info] *** 1 TEST FAILED *** +[info] 2. Monitoring source files for hello/testQuick... +[info] Press to interrupt or '?' for more options. +[info] Build triggered by /tmp/foo-build/src/test/scala/example/HelloSuite.scala. Running 'testQuick'. +[info] compiling 1 Scala source to /tmp/foo-build/target/scala-2.13/test-classes ... +HelloSuite: +==> X HelloSuite.Hello should start with H 0.004s munit.FailException: /tmp/foo-build/src/test/scala/example/HelloSuite.scala:4 assertion failed +3: test("Hello should start with H") { +4: assert("hello".startsWith("H")) +5: } +at munit.FunSuite.assert(FunSuite.scala:11) +at HelloSuite.\$anonfun\$new\$1(HelloSuite.scala:4) +[error] Failed: Total 1, Failed 1, Errors 0, Passed 0 [error] Failed tests: -[error] HelloSpec +[error] HelloSuite [error] (Test / testQuick) sbt.TestsFailedException: Tests unsuccessful ``` ### テストが通るようにする -エディタを使って `src/test/scala/HelloSpec.scala` を以下のように変更する: +エディタを使って `src/test/scala/example/HelloSuite.scala` を以下のように変更する: -@@snip [scalatest]($root$/src/sbt-test/ref/example-scalatest/changes/HelloSpec.scala) {} +@@snip [example-test]($root$/src/sbt-test/ref/example-test/changes/HelloSuite.scala) {} テストが通過したことを確認して、`Enter` を押して継続的テストを抜ける。 @@ -252,63 +266,53 @@ New York の現在の天気を調べてみる: ```scala sbt:Hello> console [info] Starting scala interpreter... -Welcome to Scala 2.12.7 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_171). +Welcome to Scala 2.13.11 (OpenJDK 64-Bit Server VM, Java 17). Type in expressions for evaluation. Or try :help. scala> :paste // Entering paste mode (ctrl-D to finish) -import scala.concurrent._, duration._ -import gigahorse._, support.okhttp.Gigahorse -import play.api.libs.json._ - -Gigahorse.withHttp(Gigahorse.config) { http => - val baseUrl = "https://www.metaweather.com/api/location" - val rLoc = Gigahorse.url(baseUrl + "/search/").get. - addQueryString("query" -> "New York") - val fLoc = http.run(rLoc, Gigahorse.asString) - val loc = Await.result(fLoc, 10.seconds) - val woeid = (Json.parse(loc) \\ 0 \\ "woeid").get - val rWeather = Gigahorse.url(baseUrl + s"/\$woeid/").get - val fWeather = http.run(rWeather, Gigahorse.asString) - val weather = Await.result(fWeather, 10.seconds) - ({Json.parse(_: String)} andThen Json.prettyPrint)(weather) -} +import sttp.client4.quick._ +import sttp.client4.Response + +val newYorkLatitude: Double = 40.7143 +val newYorkLongitude: Double = -74.006 +val response: Response[String] = quickRequest +.get( + uri"https://api.open-meteo.com/v1/forecast?latitude=\$newYorkLatitude&longitude=\$newYorkLongitude¤t_weather=true" +) +.send() -// Ctrl+D を押してペーストモードを抜ける +println(ujson.read(response.body).render(indent = 2)) + +// press Ctrl+D // Exiting paste mode, now interpreting. -import scala.concurrent._ -import duration._ -import gigahorse._ -import support.okhttp.Gigahorse -import play.api.libs.json._ -res0: String = { - "consolidated_weather" : [ { - "id" : 5325278131781632, - "weather_state_name" : "Light Rain", - "weather_state_abbr" : "lr", - "wind_direction_compass" : "W", - "created" : "2019-11-23T09:16:43.892336Z", - "applicable_date" : "2019-11-23", - "min_temp" : 0.36, - "max_temp" : 8.375, - "the_temp" : 3.98, - "wind_speed" : 4.813710565158143, - "wind_direction" : 266.48254020294627, - "air_pressure" : 1017, - "humidity" : 58, - "visibility" : 15.37583015191283, - "predictability" : 75 - }, { - "id" : 6428406054912000, - "weather_state_name" : "Heavy Rain", - "weather_state_abbr" : "hr", - ... - -scala> :q // これで REPL を抜ける + "latitude": 40.710335, + "longitude": -73.99307, + "generationtime_ms": 0.36704540252685547, + "utc_offset_seconds": 0, + "timezone": "GMT", + "timezone_abbreviation": "GMT", + "elevation": 51, + "current_weather": { + "temperature": 21.3, + "windspeed": 16.7, + "winddirection": 205, + "weathercode": 3, + "is_day": 1, + "time": "2023-08-04T10:00" + } +} +import sttp.client4.quick._ +import sttp.client4.Response +val newYorkLatitude: Double = 40.7143 +val newYorkLongitude: Double = -74.006 +val response: sttp.client4.Response[String] = Response({"latitude":40.710335,"longitude":-73.99307,"generationtime_ms":0.36704540252685547,"utc_offset_seconds":0,"timezone":"GMT","timezone_abbreviation":"GMT","elevation":51.0,"current_weather":{"temperature":21.3,"windspeed":16.7,"winddirection":205.0,"weathercode":3,"is_day":1,"time":"2023-08-04T10:00"}},200,,List(:status: 200, content-encoding: deflate, content-type: application/json; charset=utf-8, date: Fri, 04 Aug 2023 10:09:11 GMT),List(),RequestMetadata(GET,https://api.open-meteo.com/v1/forecast?latitude=40.7143&longitude... + +scala> :q // to quit ``` ### サブプロジェクトを作成する @@ -334,7 +338,7 @@ sbt:Hello> projects sbt:Hello> helloCore/compile ``` -### サブプロジェクトに ScalaTest を追加する +### サブプロジェクトに toolkit-test を追加する `build.sbt` を以下のように変更する: @@ -360,40 +364,31 @@ sbt:Hello> ~testQuick @@snip [example-sub4]($root$/src/sbt-test/ref/example-sub4/build.sbt) {} -### Play JSON を使って JSON をパースする +### uJson を使って JSON をパースする -`helloCore` に Play JSON を追加しよう。 +`helloCore` に uJson を追加しよう。 @@snip [example-weather-build]($root$/src/sbt-test/ref/example-weather/build.sbt) {} `reload` 後、`core/src/main/scala/example/core/Weather.scala` を追加する: ```scala + package example.core -import gigahorse._, support.okhttp.Gigahorse -import scala.concurrent._, duration._ -import play.api.libs.json._ +import sttp.client4.quick._ +import sttp.client4.Response object Weather { - lazy val http = Gigahorse.http(Gigahorse.config) - - def weather: Future[String] = { - val baseUrl = "https://www.metaweather.com/api/location" - val locUrl = baseUrl + "/search/" - val weatherUrl = baseUrl + "/%s/" - val rLoc = Gigahorse.url(locUrl).get. - addQueryString("query" -> "New York") - import ExecutionContext.Implicits.global - for { - loc <- http.run(rLoc, parse) - woeid = (loc \\ 0 \\ "woeid").get - rWeather = Gigahorse.url(weatherUrl format woeid).get - weather <- http.run(rWeather, parse) - } yield (weather \\\\ "weather_state_name")(0).as[String].toLowerCase - } - - private def parse = Gigahorse.asString andThen Json.parse + def temp() = { + val response: Response[String] = quickRequest + .get( + uri"https://api.open-meteo.com/v1/forecast?latitude=40.7143&longitude=-74.006¤t_weather=true" + ) + .send() + val json = ujson.read(response.body) + json.obj("current_weather")("temperature").num + } } ``` @@ -402,15 +397,13 @@ object Weather { ```scala package example -import scala.concurrent._, duration._ -import core.Weather +import example.core.Weather object Hello { - def main(args: Array[String]): Unit = { - val w = Await.result(Weather.weather, 10.seconds) - println(s"Hello! The weather in New York is \$w.") - Weather.http.close() - } + def main(args: Array[String]): Unit = { + val temp = Weather.temp() + println(s"Hello! The current temperature in New York is \$temp C.") + } } ``` @@ -418,16 +411,10 @@ object Hello { ``` sbt:Hello> run -[info] Compiling 1 Scala source to /private/tmp/foo-build/core/target/scala-2.12/classes ... -[info] Done compiling. -[info] Compiling 1 Scala source to /private/tmp/foo-build/target/scala-2.12/classes ... -[info] Packaging /private/tmp/foo-build/core/target/scala-2.12/hello-core_2.12-0.1.0-SNAPSHOT.jar ... -[info] Done packaging. -[info] Done compiling. -[info] Packaging /private/tmp/foo-build/target/scala-2.12/hello_2.12-0.1.0-SNAPSHOT.jar ... -[info] Done packaging. -[info] Running example.Hello -Hello! The weather in New York is mostly cloudy. +[info] compiling 1 Scala source to /tmp/foo-build/core/target/scala-2.13/classes ... +[info] compiling 1 Scala source to /tmp/foo-build/target/scala-2.13/classes ... +[info] running example.Hello +Hello! The current temperature in New York is 22.7 C. ``` ### sbt-native-packger プラグインを追加する @@ -442,11 +429,19 @@ Hello! The weather in New York is mostly cloudy. ### 配布用の .zip ファイルを作る + ``` +sbt:Hello> reload +... sbt:Hello> dist -[info] Wrote /private/tmp/foo-build/target/scala-2.12/hello_2.12-0.1.0-SNAPSHOT.pom -[info] Wrote /private/tmp/foo-build/core/target/scala-2.12/hello-core_2.12-0.1.0-SNAPSHOT.pom -[info] Your package is ready in /private/tmp/foo-build/target/universal/hello-0.1.0-SNAPSHOT.zip +[info] Wrote /private/tmp/foo-build/target/scala-2.13/hello_2.13-0.1.0-SNAPSHOT.pom +[info] Main Scala API documentation to /tmp/foo-build/target/scala-2.13/api... +[info] Main Scala API documentation successful. +[info] Main Scala API documentation to /tmp/foo-build/core/target/scala-2.13/api... +[info] Wrote /tmp/foo-build/core/target/scala-2.13/hello-core_2.13-0.1.0-SNAPSHOT.pom +[info] Main Scala API documentation successful. +[success] All package validations passed +[info] Your package is ready in /tmp/foo-build/target/universal/hello-0.1.0-SNAPSHOT.zip ``` パッケージ化されたアプリの実行は以下のように行う: @@ -456,25 +451,23 @@ sbt:Hello> dist \$ cd /tmp/someother \$ unzip -o -d /tmp/someother /tmp/foo-build/target/universal/hello-0.1.0-SNAPSHOT.zip \$ ./hello-0.1.0-SNAPSHOT/bin/hello -Hello! The weather in New York is mostly cloudy. -``` +Hello! The current temperature in New York is 22.7 C. +`` ### アプリを Docker化させる ``` sbt:Hello> Docker/publishLocal .... -[info] Successfully built b6ce1b6ab2c0 -[info] Successfully tagged hello:0.1.0-SNAPSHOT -[info] Built image hello:0.1.0-SNAPSHOT +[info] Built image hello with tags [0.1.0-SNAPSHOT] ``` Docker化されたアプリは以下のように実行する: ``` \$ docker run hello:0.1.0-SNAPSHOT -Hello! The weather in New York is mostly cloudy -``` +Hello! The current temperature in New York is 22.7 C. +`` ### version を設定する @@ -485,8 +478,8 @@ Hello! The weather in New York is mostly cloudy ### Switch scalaVersion temporarily ``` -sbt:Hello> ++2.12.14! -[info] Forcing Scala version to 2.12.14 on all projects. +sbt:Hello> ++3.3.0! +[info] Forcing Scala version to 3.3.0 on all projects. [info] Reapplying settings... [info] Set current project to Hello (in build file:/private/tmp/foo-build/) ``` @@ -496,9 +489,9 @@ sbt:Hello> ++2.12.14! ``` sbt:Hello> scalaVersion [info] helloCore / scalaVersion -[info] 2.12.14 +[info] 3.3.0 [info] scalaVersion -[info] 2.12.14 +[info] 3.3.0 ``` このセッティングは `reload` 後には無くなる。 @@ -527,7 +520,7 @@ sbt:Hello> inspect tree dist sbt のコマンドをターミナルから直接渡して sbt をバッチモードで実行することができる。 ``` -\$ sbt clean "testOnly HelloSpec" +\$ sbt clean "testOnly HelloSuite" ``` **Note**: バッチモードでの実行は JVM のスピンアップと JIT を毎回行うため、**ビルドかなり遅くなる。** diff --git a/src/sbt-test/ref/example-library/build.sbt b/src/sbt-test/ref/example-library/build.sbt index 276de577a..a0691af7f 100644 --- a/src/sbt-test/ref/example-library/build.sbt +++ b/src/sbt-test/ref/example-library/build.sbt @@ -1,10 +1,12 @@ -ThisBuild / scalaVersion := "2.13.6" +ThisBuild / scalaVersion := "2.13.11" ThisBuild / organization := "com.example" -lazy val hello = (project in file(".")) +lazy val hello = project + .in(file(".")) .settings( name := "Hello", - libraryDependencies += "com.typesafe.play" %% "play-json" % "2.9.2", - libraryDependencies += "com.eed3si9n" %% "gigahorse-okhttp" % "0.5.0", - libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.7" % Test, + libraryDependencies ++= Seq( + "org.scala-lang" %% "toolkit" % "0.1.7", + "org.scala-lang" %% "toolkit-test" % "0.1.7" % Test + ) ) diff --git a/src/sbt-test/ref/example-name/build.sbt b/src/sbt-test/ref/example-name/build.sbt index 5382dc93b..35361f40a 100644 --- a/src/sbt-test/ref/example-name/build.sbt +++ b/src/sbt-test/ref/example-name/build.sbt @@ -1,4 +1,4 @@ -ThisBuild / scalaVersion := "2.13.6" +ThisBuild / scalaVersion := "2.13.11" ThisBuild / organization := "com.example" lazy val hello = (project in file(".")) diff --git a/src/sbt-test/ref/example-scalatest/build.sbt b/src/sbt-test/ref/example-scalatest/build.sbt deleted file mode 100644 index 7b18718cf..000000000 --- a/src/sbt-test/ref/example-scalatest/build.sbt +++ /dev/null @@ -1,8 +0,0 @@ -ThisBuild / scalaVersion := "2.13.6" -ThisBuild / organization := "com.example" - -lazy val hello = (project in file(".")) - .settings( - name := "Hello", - libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.7" % Test, - ) diff --git a/src/sbt-test/ref/example-scalatest/changes/HelloSpec.scala b/src/sbt-test/ref/example-scalatest/changes/HelloSpec.scala deleted file mode 100644 index 939eb83e3..000000000 --- a/src/sbt-test/ref/example-scalatest/changes/HelloSpec.scala +++ /dev/null @@ -1,8 +0,0 @@ -import org.scalatest.funsuite._ - -class HelloSpec extends AnyFunSuite { - test("Hello should start with H") { - // Hello, as opposed to hello - assert("Hello".startsWith("H")) - } -} diff --git a/src/sbt-test/ref/example-scalatest/test b/src/sbt-test/ref/example-scalatest/test deleted file mode 100644 index 7c58b402e..000000000 --- a/src/sbt-test/ref/example-scalatest/test +++ /dev/null @@ -1,4 +0,0 @@ -> compile --> testQuick -$copy-file changes/HelloSpec.scala src/test/scala/HelloSpec.scala -> testQuick diff --git a/src/sbt-test/ref/example-sub1/build.sbt b/src/sbt-test/ref/example-sub1/build.sbt index bae3ed78c..a771a8160 100644 --- a/src/sbt-test/ref/example-sub1/build.sbt +++ b/src/sbt-test/ref/example-sub1/build.sbt @@ -1,14 +1,18 @@ -ThisBuild / scalaVersion := "2.13.6" +ThisBuild / scalaVersion := "2.13.11" ThisBuild / organization := "com.example" -lazy val hello = (project in file(".")) +lazy val hello = project + .in(file(".")) .settings( name := "Hello", - libraryDependencies += "com.eed3si9n" %% "gigahorse-okhttp" % "0.5.0", - libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.7" % Test, + libraryDependencies ++= Seq( + "org.scala-lang" %% "toolkit" % "0.1.7", + "org.scala-lang" %% "toolkit-test" % "0.1.7" % Test + ) ) -lazy val helloCore = (project in file("core")) +lazy val helloCore = project + .in(file("core")) .settings( - name := "Hello Core", + name := "Hello Core" ) diff --git a/src/sbt-test/ref/example-sub2/build.sbt b/src/sbt-test/ref/example-sub2/build.sbt index 73735ee84..7d82aa493 100644 --- a/src/sbt-test/ref/example-sub2/build.sbt +++ b/src/sbt-test/ref/example-sub2/build.sbt @@ -1,17 +1,21 @@ -ThisBuild / scalaVersion := "2.13.6" +ThisBuild / scalaVersion := "2.13.11" ThisBuild / organization := "com.example" -val scalaTest = "org.scalatest" %% "scalatest" % "3.2.7" +val toolkitTest = "org.scala-lang" %% "toolkit-test" % "0.1.7" -lazy val hello = (project in file(".")) +lazy val hello = project + .in(file(".")) .settings( name := "Hello", - libraryDependencies += "com.eed3si9n" %% "gigahorse-okhttp" % "0.5.0", - libraryDependencies += scalaTest % Test, + libraryDependencies ++= Seq( + "org.scala-lang" %% "toolkit" % "0.1.7", + toolkitTest % Test + ) ) -lazy val helloCore = (project in file("core")) +lazy val helloCore = project + .in(file("core")) .settings( name := "Hello Core", - libraryDependencies += scalaTest % Test, + libraryDependencies += toolkitTest % Test ) diff --git a/src/sbt-test/ref/example-sub3/build.sbt b/src/sbt-test/ref/example-sub3/build.sbt index 8a6d34118..e3a39333c 100644 --- a/src/sbt-test/ref/example-sub3/build.sbt +++ b/src/sbt-test/ref/example-sub3/build.sbt @@ -1,18 +1,22 @@ -ThisBuild / scalaVersion := "2.13.6" +ThisBuild / scalaVersion := "2.13.11" ThisBuild / organization := "com.example" -val scalaTest = "org.scalatest" %% "scalatest" % "3.2.7" +val toolkitTest = "org.scala-lang" %% "toolkit-test" % "0.1.7" -lazy val hello = (project in file(".")) +lazy val hello = project + .in(file(".")) .aggregate(helloCore) .settings( name := "Hello", - libraryDependencies += "com.eed3si9n" %% "gigahorse-okhttp" % "0.5.0", - libraryDependencies += scalaTest % Test, + libraryDependencies ++= Seq( + "org.scala-lang" %% "toolkit" % "0.1.7", + toolkitTest % Test + ) ) -lazy val helloCore = (project in file("core")) +lazy val helloCore = project + .in(file("core")) .settings( name := "Hello Core", - libraryDependencies += scalaTest % Test, + libraryDependencies += toolkitTest % Test ) diff --git a/src/sbt-test/ref/example-sub4/build.sbt b/src/sbt-test/ref/example-sub4/build.sbt index 925fec68d..2150caa7f 100644 --- a/src/sbt-test/ref/example-sub4/build.sbt +++ b/src/sbt-test/ref/example-sub4/build.sbt @@ -1,19 +1,21 @@ -ThisBuild / scalaVersion := "2.13.6" +ThisBuild / scalaVersion := "2.13.11" ThisBuild / organization := "com.example" -val scalaTest = "org.scalatest" %% "scalatest" % "3.2.7" +val toolkitTest = "org.scala-lang" %% "toolkit-test" % "0.1.7" -lazy val hello = (project in file(".")) +lazy val hello = project + .in(file(".")) .aggregate(helloCore) .dependsOn(helloCore) .settings( name := "Hello", - libraryDependencies += scalaTest % Test, + libraryDependencies += toolkitTest % Test ) -lazy val helloCore = (project in file("core")) +lazy val helloCore = project + .in(file("core")) .settings( name := "Hello Core", - libraryDependencies += "com.eed3si9n" %% "gigahorse-okhttp" % "0.5.0", - libraryDependencies += scalaTest % Test, + libraryDependencies += "org.scala-lang" %% "toolkit" % "0.1.7", + libraryDependencies += toolkitTest % Test ) diff --git a/src/sbt-test/ref/example-test/build.sbt b/src/sbt-test/ref/example-test/build.sbt new file mode 100644 index 000000000..07208f11a --- /dev/null +++ b/src/sbt-test/ref/example-test/build.sbt @@ -0,0 +1,9 @@ +ThisBuild / scalaVersion := "2.13.11" +ThisBuild / organization := "com.example" + +lazy val hello = project + .in(file(".")) + .settings( + name := "Hello", + libraryDependencies += "org.scala-lang" %% "toolkit-test" % "0.1.7" % Test + ) diff --git a/src/sbt-test/ref/example-test/changes/HelloSuite.scala b/src/sbt-test/ref/example-test/changes/HelloSuite.scala new file mode 100644 index 000000000..e9ab5344b --- /dev/null +++ b/src/sbt-test/ref/example-test/changes/HelloSuite.scala @@ -0,0 +1,6 @@ + +class HelloSuite extends munit.FunSuite { + test("Hello should start with H") { + assert("Hello".startsWith("H")) + } +} diff --git a/src/sbt-test/ref/example-scalatest/src/test/scala/HelloSpec.scala b/src/sbt-test/ref/example-test/src/test/scala/example/HelloSuite.scala similarity index 53% rename from src/sbt-test/ref/example-scalatest/src/test/scala/HelloSpec.scala rename to src/sbt-test/ref/example-test/src/test/scala/example/HelloSuite.scala index 1553617ac..0f05e9bcc 100644 --- a/src/sbt-test/ref/example-scalatest/src/test/scala/HelloSpec.scala +++ b/src/sbt-test/ref/example-test/src/test/scala/example/HelloSuite.scala @@ -1,6 +1,5 @@ -import org.scalatest.funsuite._ -class HelloSpec extends AnyFunSuite { +class HelloSuite extends munit.FunSuite { test("Hello should start with H") { assert("hello".startsWith("H")) } diff --git a/src/sbt-test/ref/example-test/test b/src/sbt-test/ref/example-test/test new file mode 100644 index 000000000..c76c270bc --- /dev/null +++ b/src/sbt-test/ref/example-test/test @@ -0,0 +1,4 @@ +> compile +-> testQuick +$copy-file changes/HelloSuite.scala src/test/scala/example/HelloSuite.scala +> testQuick diff --git a/src/sbt-test/ref/example-weather/build.sbt b/src/sbt-test/ref/example-weather/build.sbt index 12ad38421..2150caa7f 100644 --- a/src/sbt-test/ref/example-weather/build.sbt +++ b/src/sbt-test/ref/example-weather/build.sbt @@ -1,21 +1,21 @@ -ThisBuild / scalaVersion := "2.13.6" +ThisBuild / scalaVersion := "2.13.11" ThisBuild / organization := "com.example" -val scalaTest = "org.scalatest" %% "scalatest" % "3.2.7" -val gigahorse = "com.eed3si9n" %% "gigahorse-okhttp" % "0.5.0" -val playJson = "com.typesafe.play" %% "play-json" % "2.9.2" +val toolkitTest = "org.scala-lang" %% "toolkit-test" % "0.1.7" -lazy val hello = (project in file(".")) +lazy val hello = project + .in(file(".")) .aggregate(helloCore) .dependsOn(helloCore) .settings( name := "Hello", - libraryDependencies += scalaTest % Test, + libraryDependencies += toolkitTest % Test ) -lazy val helloCore = (project in file("core")) +lazy val helloCore = project + .in(file("core")) .settings( name := "Hello Core", - libraryDependencies ++= Seq(gigahorse, playJson), - libraryDependencies += scalaTest % Test, + libraryDependencies += "org.scala-lang" %% "toolkit" % "0.1.7", + libraryDependencies += toolkitTest % Test ) diff --git a/src/sbt-test/ref/example-weather/changes/build.sbt b/src/sbt-test/ref/example-weather/changes/build.sbt index b713aa0c1..3083521a5 100644 --- a/src/sbt-test/ref/example-weather/changes/build.sbt +++ b/src/sbt-test/ref/example-weather/changes/build.sbt @@ -1,22 +1,23 @@ -ThisBuild / scalaVersion := "2.13.6" +ThisBuild / scalaVersion := "2.13.11" ThisBuild / organization := "com.example" -val scalaTest = "org.scalatest" %% "scalatest" % "3.2.7" -val gigahorse = "com.eed3si9n" %% "gigahorse-okhttp" % "0.5.0" -val playJson = "com.typesafe.play" %% "play-json" % "2.9.2" +val toolkitTest = "org.scala-lang" %% "toolkit-test" % "0.1.7" -lazy val hello = (project in file(".")) +lazy val hello = project + .in(file(".")) .aggregate(helloCore) .dependsOn(helloCore) .enablePlugins(JavaAppPackaging) .settings( name := "Hello", - libraryDependencies += scalaTest % Test, + libraryDependencies += toolkitTest % Test, + maintainer := "A Scala Dev!" ) -lazy val helloCore = (project in file("core")) +lazy val helloCore = project + .in(file("core")) .settings( name := "Hello Core", - libraryDependencies ++= Seq(gigahorse, playJson), - libraryDependencies += scalaTest % Test, + libraryDependencies += "org.scala-lang" %% "toolkit" % "0.1.7", + libraryDependencies += toolkitTest % Test ) diff --git a/src/sbt-test/ref/example-weather/changes/build3.sbt b/src/sbt-test/ref/example-weather/changes/build3.sbt index d434adf75..fe47531c0 100644 --- a/src/sbt-test/ref/example-weather/changes/build3.sbt +++ b/src/sbt-test/ref/example-weather/changes/build3.sbt @@ -1,23 +1,24 @@ -ThisBuild / version := "0.1.0" -ThisBuild / scalaVersion := "2.13.6" +ThisBuild / version := "0.1.0" +ThisBuild / scalaVersion := "2.13.11" ThisBuild / organization := "com.example" -val scalaTest = "org.scalatest" %% "scalatest" % "3.2.7" -val gigahorse = "com.eed3si9n" %% "gigahorse-okhttp" % "0.5.0" -val playJson = "com.typesafe.play" %% "play-json" % "2.9.2" +val toolkitTest = "org.scala-lang" %% "toolkit-test" % "0.1.7" -lazy val hello = (project in file(".")) +lazy val hello = project + .in(file(".")) .aggregate(helloCore) .dependsOn(helloCore) .enablePlugins(JavaAppPackaging) .settings( name := "Hello", - libraryDependencies += scalaTest % Test, + libraryDependencies += toolkitTest % Test, + maintainer := "A Scala Dev!" ) -lazy val helloCore = (project in file("core")) +lazy val helloCore = project + .in(file("core")) .settings( name := "Hello Core", - libraryDependencies ++= Seq(gigahorse, playJson), - libraryDependencies += scalaTest % Test, + libraryDependencies += "org.scala-lang" %% "toolkit" % "0.1.7", + libraryDependencies += toolkitTest % Test ) diff --git a/src/sbt-test/ref/example-weather/changes/plugins.sbt b/src/sbt-test/ref/example-weather/changes/plugins.sbt index 84668ba94..9a1605498 100644 --- a/src/sbt-test/ref/example-weather/changes/plugins.sbt +++ b/src/sbt-test/ref/example-weather/changes/plugins.sbt @@ -1 +1 @@ -addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.3.4") +addSbtPlugin("com.github.sbt" % "sbt-native-packager" % "1.9.4") diff --git a/src/sbt-test/ref/example-weather/core/src/main/scala/example/core/Weather.scala b/src/sbt-test/ref/example-weather/core/src/main/scala/example/core/Weather.scala index 7f6de5f40..aedc6af3a 100644 --- a/src/sbt-test/ref/example-weather/core/src/main/scala/example/core/Weather.scala +++ b/src/sbt-test/ref/example-weather/core/src/main/scala/example/core/Weather.scala @@ -1,26 +1,19 @@ package example.core -import gigahorse._, support.okhttp.Gigahorse -import scala.concurrent._, duration._ -import play.api.libs.json._ +import sttp.client4.quick._ +import sttp.client4.Response object Weather { - lazy val http = Gigahorse.http(Gigahorse.config) - - def weather: Future[String] = { - val baseUrl = "https://www.metaweather.com/api/location" - val locUrl = baseUrl + "/search/" - val weatherUrl = baseUrl + "/%s/" - val rLoc = Gigahorse.url(locUrl).get. - addQueryString("query" -> "New York") - import ExecutionContext.Implicits.global - for { - loc <- http.run(rLoc, parse) - woeid = (loc \ 0 \ "woeid").get - rWeather = Gigahorse.url(weatherUrl format woeid).get - weather <- http.run(rWeather, parse) - } yield (weather \\ "weather_state_name")(0).as[String].toLowerCase + def weather() = { + val response: Response[String] = quickRequest + .get( + uri"https://api.open-meteo.com/v1/forecast?latitude=$newYorkLatitude&longitude=$newYorkLongitude¤t_weather=true" + ) + .send() + val json = ujson.read(response.body) + json.obj("current_weather")("temperature").num } - private def parse = Gigahorse.asString andThen Json.parse + private val newYorkLatitude: Double = 40.7143 + private val newYorkLongitude: Double = -74.006 } diff --git a/src/sbt-test/ref/example-weather/src/main/scala/example/Hello.scala b/src/sbt-test/ref/example-weather/src/main/scala/example/Hello.scala index d1c81d0d4..84f5b5b6a 100644 --- a/src/sbt-test/ref/example-weather/src/main/scala/example/Hello.scala +++ b/src/sbt-test/ref/example-weather/src/main/scala/example/Hello.scala @@ -1,12 +1,10 @@ package example -import scala.concurrent._, duration._ -import core.Weather +import example.core.Weather object Hello { def main(args: Array[String]): Unit = { - val w = Await.result(Weather.weather, 10.seconds) - println(s"Hello! The weather in New York is $w.") - Weather.http.close() + val temp = Weather.weather() + println(s"Hello! The current temperature in New York is $temp C.") } } diff --git a/src/sbt-test/ref/example-weather/pending b/src/sbt-test/ref/example-weather/test similarity index 100% rename from src/sbt-test/ref/example-weather/pending rename to src/sbt-test/ref/example-weather/test