diff --git a/.travis.yml b/.travis.yml index f3252bde..e6ac2997 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,26 +1,20 @@ language: scala scala: - - 2.10.6 - - 2.11.11 + - 2.11.12 + - 2.12.7 jdk: - - oraclejdk7 - oraclejdk8 - -matrix: - include: - - scala: 2.12.2 - jdk: oraclejdk8 - env: - - TRAVIS_NODE_VERSION="6" + - openjdk11 branches: except: - /^wip-.*$/ env: - - TRAVIS_NODE_VERSION="6" + - TRAVIS_NODE_VERSION="10.9.0" SCALAJS_VERSION="0.6.25" + - TRAVIS_NODE_VERSION="10.9.0" SCALAJS_VERSION="1.0.0-M6" install: - rm -rf ~/.nvm && git clone https://github.com/creationix/nvm.git ~/.nvm && (cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`) && source ~/.nvm/nvm.sh && nvm install $TRAVIS_NODE_VERSION @@ -41,9 +35,9 @@ before_cache: script: # Your normal script - - sbt ++$TRAVIS_SCALA_VERSION squantsJVM/test:compile squantsJS/test:compile squantsJS/fastOptJS - - if [[ $TRAVIS_SCALA_VERSION == "2.11.11" ]]; then sbt ++$TRAVIS_SCALA_VERSION squantsNative/compile; fi; - - sbt ++$TRAVIS_SCALA_VERSION squantsJS/test squantsJVM/test + - sbt ++$TRAVIS_SCALA_VERSION squantsJVM/compile squantsJS/compile squantsJS/fastOptJS + - if [[ $TRAVIS_SCALA_VERSION == "2.11.12" ]]; then sbt ++$TRAVIS_SCALA_VERSION squantsNative/compile; fi; + - if [[ $SCALAJS_VERSION == "0.6.25" ]]; then sbt ++$TRAVIS_SCALA_VERSION squantsJS/test squantsJVM/test; fi; - sbt ++$TRAVIS_SCALA_VERSION squantsJS/doc squantsJVM/doc tut # Tricks to avoid unnecessary cache updates diff --git a/README.md b/README.md index cc3e6da5..17e1386e 100644 --- a/README.md +++ b/README.md @@ -15,17 +15,17 @@ All types are immutable and thread-safe. | [![Join the chat at https://gitter.im/typelevel/squants](https://badges.gitter.im/typelevel/squants.svg)](https://gitter.im/typelevel/squants?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) | -[![Scaladocs](https://www.javadoc.io/badge/org.typelevel/squants_2.12.svg?label=scaladoc)](https://static.javadoc.io/org.typelevel/squants_2.12/1.2.0/squants/index.html) +[![Scaladocs](https://www.javadoc.io/badge/org.typelevel/squants_2.12.svg?label=scaladoc)](https://static.javadoc.io/org.typelevel/squants_2.12/1.4.0/squants/index.html) | [![Build Status](https://travis-ci.org/typelevel/squants.png?branch=master)](https://travis-ci.org/typelevel/squants) ### Current Versions -Current Release: **1.3.0** -([API Docs](https://oss.sonatype.org/service/local/repositories/releases/archive/org/typelevel/squants_2.11/1.3.0/squants_2.11-1.3.0-javadoc.jar/!/index.html#squants.package)) +Current Release: **1.4.0** +([API Docs](https://oss.sonatype.org/service/local/repositories/releases/archive/org/typelevel/squants_2.12/1.4.0/squants_2.12-1.4.0-javadoc.jar/!/index.html#squants.package)) -Development Build: **1.4.0-SNAPSHOT** -([API Docs](https://oss.sonatype.org/service/local/repositories/snapshots/archive/org/typelevel/squants_2.11/1.4.0-SNAPSHOT/squants_2.11-1.4.0-SNAPSHOT-javadoc.jar/!/index.html#squants.package)) +Development Build: **1.5.0-SNAPSHOT** +([API Docs](https://oss.sonatype.org/service/local/repositories/snapshots/archive/org/typelevel/squants_2.12/1.5.0-SNAPSHOT/squants_2.12-1.5.0-SNAPSHOT-javadoc.jar/!/index.html#squants.package)) [Release History](https://github.com/typelevel/squants/wiki/Release-History) @@ -38,10 +38,10 @@ For more information on feature availability of a specific version see the Relea Repository hosting for Squants is provided by [Sonatype](https://oss.sonatype.org/). To use Squants in your SBT project add the following dependency to your build. - "org.typelevel" %% "squants" % "1.3.0" + "org.typelevel" %% "squants" % "1.4.0" or - "org.typelevel" %% "squants" % "1.4.0-SNAPSHOT" + "org.typelevel" %% "squants" % "1.5.0-SNAPSHOT" To use Squants in your Maven project add the following dependency @@ -50,12 +50,13 @@ To use Squants in your Maven project add the following dependency org.typelevel squants_2.11 - 1.3.0 + 1.4.0 ``` Beginning with Squants 0.4.x series, both Scala 2.10 and 2.11 builds are available. Beginning with Squants 1.x series, Scala 2.10, 2.11 and 2.12 builds are available. +Scala.js is supported on version 0.6.25 and 1.0.0-M6 To use Squants interactively in the Scala REPL, clone the git repo and run `sbt squantsJVM/console` @@ -506,16 +507,16 @@ scala> import squants.market.{BTC, JPY, USD, XAU} import squants.market.{BTC, JPY, USD, XAU} scala> val tenBucks = USD(10) // Money: 10 USD -tenBucks: squants.market.Money = 10.0 USD +tenBucks: squants.market.Money = 1E+1 USD scala> val someYen = JPY(1200) // Money: 1200 JPY -someYen: squants.market.Money = 1200.0 JPY +someYen: squants.market.Money = 1.2E+3 JPY scala> val goldStash = XAU(50) // Money: 50 XAU -goldStash: squants.market.Money = 50.0 XAU +goldStash: squants.market.Money = 5E+1 XAU scala> val digitalCache = BTC(50) // Money: 50 BTC -digitalCache: squants.market.Money = 50.0 BTC +digitalCache: squants.market.Money = 5E+1 BTC ``` ### Price @@ -535,16 +536,16 @@ import squants.space.UsGallons You can compute the following: ```scala scala> val threeForADollar = USD(1) / Each(3) -threeForADollar: squants.market.Price[squants.Dimensionless] = 1.0 USD/3.0 ea +threeForADollar: squants.market.Price[squants.Dimensionless] = 1 USD/3.0 ea scala> val energyPrice = USD(102.20) / MegawattHours(1) energyPrice: squants.market.Price[squants.energy.Energy] = 102.2 USD/1.0 MWh scala> val milkPrice = USD(4) / UsGallons(1) -milkPrice: squants.market.Price[squants.space.Volume] = 4.0 USD/1.0 gal +milkPrice: squants.market.Price[squants.space.Volume] = 4 USD/1.0 gal scala> val costForABunch = threeForADollar * Dozen(10) -costForABunch: squants.market.Money = 40.0 USD +costForABunch: squants.market.Money = 4E+1 USD scala> val energyCost = energyPrice * MegawattHours(4) energyCost: squants.market.Money = 408.8 USD @@ -582,14 +583,14 @@ rate2: squants.market.CurrencyExchangeRate = USD/JPY 100.0 scala> // OR | val rate3 = JPY(100) -> USD(1) -rate3: (squants.market.Money, squants.market.Money) = (100.0 JPY,1.0 USD) +rate3: squants.market.CurrencyExchangeRate = USD/JPY 100.0 scala> // OR | val rate4 = JPY(100) toThe USD(1) rate4: squants.market.CurrencyExchangeRate = USD/JPY 100.0 scala> val someYen: Money = JPY(350) -someYen: squants.market.Money = 350.0 JPY +someYen: squants.market.Money = 3.5E+2 JPY scala> val someBucks: Money = USD(23.50) someBucks: squants.market.Money = 23.5 USD @@ -602,7 +603,7 @@ scala> val dollarAmount: Money = rate1.convert(someYen) dollarAmount: squants.market.Money = 3.5 USD scala> val yenAmount: Money = rate1.convert(someBucks) -yenAmount: squants.market.Money = 2350.0 JPY +yenAmount: squants.market.Money = 2.35E+3 JPY ``` Or just use the `*` operator in either direction (money * rate, or rate * money): @@ -611,7 +612,7 @@ scala> val dollarAmount2: Money = rate1 * someYen dollarAmount2: squants.market.Money = 3.5 USD scala> val yenAmount2: Money = someBucks * rate1 -yenAmount2: squants.market.Money = 2350.0 JPY +yenAmount2: squants.market.Money = 2.35E+3 JPY ``` ### Money Context @@ -633,25 +634,25 @@ scala> val exchangeRates = List(USD / CAD(1.05), USD / MXN(12.50), USD / JPY(100 exchangeRates: List[squants.market.CurrencyExchangeRate] = List(USD/CAD 1.05, USD/MXN 12.5, USD/JPY 100.0) scala> implicit val moneyContext = defaultMoneyContext withExchangeRates exchangeRates -moneyContext: squants.market.MoneyContext = MoneyContext(DefaultCurrency(USD),Currencies(ARS,AUD,BRL,BTC,CAD,CHF,CLP,CNY,CZK,DKK,EUR,GBP,HKD,INR,JPY,KRW,MXN,MYR,NOK,NZD,RUB,SEK,USD,XAG,XAU),ExchangeRates(USD/CAD 1.05,USD/JPY 100.0,USD/MXN 12.5),AllowIndirectConversions(true)) +moneyContext: squants.market.MoneyContext = MoneyContext(DefaultCurrency(USD),Currencies(ARS,AUD,BRL,BTC,CAD,CHF,CLP,CNY,CZK,DKK,ETH,EUR,GBP,HKD,INR,JPY,KRW,LTC,MXN,MYR,NAD,NOK,NZD,RUB,SEK,USD,XAG,XAU,ZAR),ExchangeRates(USD/CAD 1.05,USD/JPY 100.0,USD/MXN 12.5),AllowIndirectConversions(true)) scala> val energyPrice = USD(102.20) / MegawattHours(1) energyPrice: squants.market.Price[squants.energy.Energy] = 102.2 USD/1.0 MWh scala> val someMoney = Money(350) // 350 in the default Cur -someMoney: squants.market.Money = 350.0 USD +someMoney: squants.market.Money = 3.5E+2 USD scala> val usdMoney: Money = someMoney in USD -usdMoney: squants.market.Money = 350.0 USD +usdMoney: squants.market.Money = 3.5E+2 USD scala> val usdBigDecimal: BigDecimal = someMoney to USD usdBigDecimal: BigDecimal = 350.0 scala> val yenCost: Money = (energyPrice * MegawattHours(5)) in JPY -yenCost: squants.market.Money = 51100.0 JPY +yenCost: squants.market.Money = 5.11E+4 JPY scala> val northAmericanSales: Money = (CAD(275) + USD(350) + MXN(290)) in USD -northAmericanSales: squants.market.Money = 635.1047619047619 USD +northAmericanSales: squants.market.Money = 635.1047619047619047619047619047619 USD ``` ## Quantity Ranges @@ -691,10 +692,10 @@ This will fail because `lower` = `upper`: scala> QuantityRange(1.km, 1.km) java.lang.IllegalArgumentException: QuantityRange upper bound must be strictly greater than to the lower bound at squants.QuantityRange.(QuantityRange.scala:25) - ... 1023 elided + ... 44 elided ``` -`QuantityRange` contains two functions that check if an element is part of the range, `contains` and `includes`. +`QuantityRange` contains two functions that check if an element is part of the range, `contains` and `includes`. These differ in how they treat the range's upper bound: `contains()` _excludes_ it but `includes()` _includes_ it. ```scala @@ -735,7 +736,7 @@ val rs3 = range / Kilowatts(400) ### QuantityRange operations `QuantityRange` supports foreach, map, and foldLeft/foldRight. These vary slightly from the versions -in the Scala standard library in that they take a divisior as the first parameter. The examples below +in the Scala standard library in that they take a divisior as the first parameter. The examples below illustrate their use. Subdivide range into 1-Megawatt "slices", and foreach over each of slices: @@ -858,10 +859,10 @@ speed: squants.motion.Velocity = 27.77777777777778 m/s scala> // MegawattHours(1) == 1.megawattHours == megawattHour == MWh | val hi = 100.dollars / MWh -hi: squants.market.Price[squants.energy.Energy] = 100.0 USD/1.0 MWh +hi: squants.market.Price[squants.energy.Energy] = 1E+2 USD/1.0 MWh scala> val low = 40.dollars / megawattHour -low: squants.market.Price[squants.energy.Energy] = 40.0 USD/1.0 MWh +low: squants.market.Price[squants.energy.Energy] = 4E+1 USD/1.0 MWh ``` Implicit conversion support for using Doubles, Longs and BigDecimals on the left side of multiply and divide operations: @@ -924,10 +925,10 @@ implicit val moneyContext = defaultMoneyContext ```scala scala> implicit val moneyNum = new MoneyNumeric() -moneyNum: squants.market.MoneyConversions.MoneyNumeric = MoneyNumeric(MoneyContext(DefaultCurrency(USD),Currencies(ARS,AUD,BRL,BTC,CAD,CHF,CLP,CNY,CZK,DKK,EUR,GBP,HKD,INR,JPY,KRW,MXN,MYR,NOK,NZD,RUB,SEK,USD,XAG,XAU),ExchangeRates(),AllowIndirectConversions(true))) +moneyNum: squants.market.MoneyConversions.MoneyNumeric = MoneyNumeric(MoneyContext(DefaultCurrency(USD),Currencies(ARS,AUD,BRL,BTC,CAD,CHF,CLP,CNY,CZK,DKK,ETH,EUR,GBP,HKD,INR,JPY,KRW,LTC,MXN,MYR,NAD,NOK,NZD,RUB,SEK,USD,XAG,XAU,ZAR),ExchangeRates(),AllowIndirectConversions(true))) scala> val sum = List(USD(100), USD(10)).sum -sum: squants.market.Money = 110.0 USD +sum: squants.market.Money = 1.1E+2 USD ``` ## Unit groups @@ -962,7 +963,7 @@ import squants.experimental.unitgroups.si.strict.implicits._ // import squants.experimental.unitgroups.si.strict.implicits._ val siLengths: UnitGroup[Length] = implicitly[UnitGroup[Length]] -// siLengths: squants.experimental.unitgroups.UnitGroup[squants.space.Length] = squants.experimental.unitgroups.si.strict.package$implicits$$anon$1@264b156b +// siLengths: squants.experimental.unitgroups.UnitGroup[squants.space.Length] = squants.experimental.unitgroups.si.strict.package$implicits$$anon$1@71f1bb6 ``` To print out units and their conversion factors to the primary SI unit, you could use this code: @@ -1015,20 +1016,20 @@ import squants.space._ import squants.experimental.unitgroups.UnitGroup // import squants.experimental.unitgroups.UnitGroup -val usCookingUnitGroup = new UnitGroup[Volume] { +val usCookingUnitGroup = new UnitGroup[Volume] { // units don't have to be specified in-order. val units: Set[UnitOfMeasure[Volume]] = Set(UsPints, UsGallons, Teaspoons, Tablespoons, UsQuarts, FluidOunces) } -// usCookingUnitGroup: squants.experimental.unitgroups.UnitGroup[squants.space.Volume]{val units: Set[squants.UnitOfMeasure[squants.space.Volume]]} = $anon$1@27b100b6 +// usCookingUnitGroup: squants.experimental.unitgroups.UnitGroup[squants.space.Volume]{val units: Set[squants.UnitOfMeasure[squants.space.Volume]]} = $anon$1@608b512 // squants automatically sorts units usCookingUnitGroup.sortedUnits.foreach(println) -// squants.space.Teaspoons$@525d11ee -// squants.space.Tablespoons$@4037896b -// squants.space.FluidOunces$@1d59b092 -// squants.space.UsPints$@5fd4d32b -// squants.space.UsQuarts$@390357cd -// squants.space.UsGallons$@48cd8671 +// squants.space.Teaspoons$@6c8ced06 +// squants.space.Tablespoons$@34fbe7f5 +// squants.space.FluidOunces$@d678d65 +// squants.space.UsPints$@71e9406b +// squants.space.UsQuarts$@f2a1319 +// squants.space.UsGallons$@6e8d9849 ``` The `UnitGroup` values provided with Squants are only samples and aren't intended to be exhaustive. @@ -1037,7 +1038,7 @@ applicable. ## Formatters -Squants provides an experimental API for formatting Quantities in the "best unit." For example, +Squants provides an experimental API for formatting Quantities in the "best unit." For example, convert Inches(12) to Feet(1). This is useful for producing human-friendly output. To use a formatter, you must implement the `squants.formatters.Formatter` trait: @@ -1050,7 +1051,7 @@ trait Formatter[A <: Quantity[A]] { ### Default Formatter implementation -There is a default formatter implementation in `squants.experimental.formatter.DefaultFormatter`. This builds on the `UnitGroup` +There is a default formatter implementation in `squants.experimental.formatter.DefaultFormatter`. This builds on the `UnitGroup` API discussed above to choose the best `UnitOfMeasure` for a `Quantity`. The `DefaultFormatter` algorithm will probably work for most use-cases, but users can create their own `Formatters` if they have custom needs. @@ -1064,7 +1065,7 @@ import squants.experimental.unitgroups.misc.AstronomicalLengthUnitGroup Then create the formatter by passing in a unit group: ```scala val astroFormatter = new DefaultFormatter(AstronomicalLengthUnitGroup) -// astroFormatter: squants.experimental.formatter.DefaultFormatter[squants.space.Length] = squants.experimental.formatter.DefaultFormatter@22aa737b +// astroFormatter: squants.experimental.formatter.DefaultFormatter[squants.space.Length] = squants.experimental.formatter.DefaultFormatter@36136e90 ``` Now, we create some values using human-unfriendly numbers: @@ -1116,7 +1117,7 @@ import squants.experimental.unitgroups.misc.AstronomicalLengthUnitGroup ```scala implicit val astroFormatter = new DefaultFormatter(AstronomicalLengthUnitGroup) -// astroFormatter: squants.experimental.formatter.DefaultFormatter[squants.space.Length] = squants.experimental.formatter.DefaultFormatter@652e1c16 +// astroFormatter: squants.experimental.formatter.DefaultFormatter[squants.space.Length] = squants.experimental.formatter.DefaultFormatter@5866ca54 val earthToJupiter = 588000000.km // earthToJupiter: squants.space.Length = 588000000.0 km @@ -1148,7 +1149,7 @@ scala> 5000.grams.inBestUnit ### SI Formatters and implicit syntax -When using SI units, and the default formatter algorithm, you don't have to declare a `Formatter` and place it in +When using SI units, and the default formatter algorithm, you don't have to declare a `Formatter` and place it in implicit scope. The compiler can do that for you. This creates a very human-friendly API by using the appropriate imports. @@ -1321,7 +1322,7 @@ import squants.time.TimeConversions._ ```scala scala> implicit val moneyContext = defaultMoneyContext -moneyContext: squants.market.MoneyContext = MoneyContext(DefaultCurrency(USD),Currencies(ARS,AUD,BRL,BTC,CAD,CHF,CLP,CNY,CZK,DKK,EUR,GBP,HKD,INR,JPY,KRW,MXN,MYR,NOK,NZD,RUB,SEK,USD,XAG,XAU),ExchangeRates(),AllowIndirectConversions(true)) +moneyContext: squants.market.MoneyContext = MoneyContext(DefaultCurrency(USD),Currencies(ARS,AUD,BRL,BTC,CAD,CHF,CLP,CNY,CZK,DKK,ETH,EUR,GBP,HKD,INR,JPY,KRW,LTC,MXN,MYR,NAD,NOK,NZD,RUB,SEK,USD,XAG,XAU,ZAR),ExchangeRates(),AllowIndirectConversions(true)) scala> val energyPrice: Price[Energy] = 45.25.money / megawattHour energyPrice: squants.market.Price[squants.energy.Energy] = 45.25 USD/1.0 MWh @@ -1330,7 +1331,7 @@ scala> val energyUsage: Energy = 345.kilowatts * 5.4.hours energyUsage: squants.energy.Energy = 1863000.0000000002 Wh scala> val energyCost: Money = energyPrice * energyUsage -energyCost: squants.market.Money = 84.30075000000001 USD +energyCost: squants.market.Money = 84.30075000000000905 USD scala> val dodgeViper: Acceleration = 60.miles / hour / 3.9.seconds dodgeViper: squants.motion.Acceleration = 6.877552216615386 m/s² @@ -1551,6 +1552,11 @@ To make a release do the following: sbt squantsNative/publishSigned ``` +* Repeat for scala.js 1.0.0-M6 +``` + SCALAJS_VERSION=1.0.0-M6 sbt +squantsJS/publishSigned +``` + * Then make a release (Note: after this step the release cannot be replaced) ``` sbt sonatypeRelease diff --git a/build.sbt b/build.sbt index f30c8e7c..15d567a4 100644 --- a/build.sbt +++ b/build.sbt @@ -1,27 +1,32 @@ -import sbtcrossproject.{crossProject, CrossType} +import sbtcrossproject.CrossPlugin.autoImport.{crossProject, CrossType} lazy val defaultSettings = Project.defaultSettings ++ Compiler.defaultSettings ++ Publish.defaultSettings ++ - Tests.defaultSettings ++ Formatting.defaultSettings ++ Console.defaultSettings ++ Docs.defaultSettings -lazy val squants = crossProject(JSPlatform, JVMPlatform, NativePlatform) +lazy val squants = + crossProject(JSPlatform, JVMPlatform, NativePlatform) .crossType(CrossType.Full) .in(file(".")) .settings(defaultSettings: _*) + .jvmConfigure( + _.enablePlugins(TutPlugin, SbtOsgi) + ) .jvmSettings( osgiSettings, tutTargetDirectory := file("."), tutSourceDirectory := file("shared") / "src" / "main" / "tut" ) + .jvmSettings(Tests.defaultSettings: _*) .jsSettings( parallelExecution in Test := false, excludeFilter in Test := "*Serializer.scala" || "*SerializerSpec.scala" ) + .jsSettings(Tests.defaultSettings: _*) lazy val root = project.in(file(".")) .settings(defaultSettings: _*) @@ -31,8 +36,4 @@ lazy val root = project.in(file(".")) publishLocal := {}, publishArtifact := false ) - .aggregate(squantsJVM, squantsJS, squantsNative) - -lazy val squantsJVM = squants.jvm.enablePlugins(TutPlugin, SbtOsgi) -lazy val squantsJS = squants.js -lazy val squantsNative = squants.native + .aggregate(squants.jvm, squants.js, squants.native) diff --git a/project/Build.scala b/project/Build.scala index bf03b5a1..eb7ab865 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1,17 +1,26 @@ -import org.scalajs.sbtplugin.ScalaJSPlugin.autoImport._ +import org.portablescala.sbtplatformdeps.PlatformDepsPlugin.autoImport._ +import sbtcrossproject.CrossPlugin.autoImport.{crossProject, CrossType} +import scalanativecrossproject.ScalaNativeCrossPlugin.autoImport._ import sbt.Keys._ import sbt._ import com.typesafe.sbt.osgi.SbtOsgi import com.typesafe.sbt.osgi.SbtOsgi.autoImport._ object Versions { - val Squants = "1.3.0" - val Scala = "2.11.11" - val ScalaCross = Seq("2.12.2", "2.11.11", "2.10.6") + val Squants = "1.4.0" + val Scala = "2.11.12" // Don't use 2.12 yet to avoid troubles with native + val scalaJSVersion = + Option(System.getenv("SCALAJS_VERSION")).getOrElse("0.6.25") + val ScalaCross = + if (scalaJSVersion.startsWith("0.6")) { + Seq("2.10.7", "2.11.12", "2.12.7") + } else { + Seq("2.11.12", "2.12.7") + } - val ScalaTest = "3.0.3" + val ScalaTest = "3.0.5" val ScalaCheck = "1.13.5" - val Json4s = "3.5.1" + val Json4s = "3.6.1" } object Dependencies { @@ -114,12 +123,17 @@ object Publish { } object Tests { - val defaultSettings = Seq( - libraryDependencies ++= - Dependencies.scalaTest.value ++ - Dependencies.scalaCheck.value ++ - Dependencies.json4s.value - ) + val defaultSettings = + if (Versions.scalaJSVersion.startsWith("0.6")) { + Seq( + libraryDependencies ++= + Dependencies.scalaTest.value ++ + Dependencies.scalaCheck.value ++ + Dependencies.json4s.value + ) + } else { + Seq.empty + } } object Formatting { diff --git a/project/build.properties b/project/build.properties index 64cf32f7..7c58a83a 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.1.4 +sbt.version=1.2.6 diff --git a/project/plugins.sbt b/project/plugins.sbt index e96368d0..e914dd82 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,7 +1,10 @@ -addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "0.4.0") -addSbtPlugin("org.portable-scala" % "sbt-scala-native-crossproject" % "0.4.0") -addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.22") -addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.3.7") +addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "0.6.0") +addSbtPlugin("org.portable-scala" % "sbt-scala-native-crossproject" % "0.6.0") +val scalaJSVersion = + Option(System.getenv("SCALAJS_VERSION")).getOrElse("0.6.25") + +addSbtPlugin("org.scala-js" % "sbt-scalajs" % scalaJSVersion) +addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.3.8") addSbtPlugin("org.scalariform" % "sbt-scalariform" % "1.8.2") @@ -11,4 +14,4 @@ addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.1.1") addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "2.3") -addSbtPlugin("org.tpolecat" % "tut-plugin" % "0.6.4") +addSbtPlugin("org.tpolecat" % "tut-plugin" % "0.6.9") diff --git a/shared/src/main/scala/squants/energy/Power.scala b/shared/src/main/scala/squants/energy/Power.scala index a0f1a672..194e4766 100644 --- a/shared/src/main/scala/squants/energy/Power.scala +++ b/shared/src/main/scala/squants/energy/Power.scala @@ -10,7 +10,7 @@ package squants.energy import squants._ import squants.electro.{ Amperes, ElectricCurrent, ElectricPotential, Volts } -import squants.radio.{ Irradiance, RadiantIntensity, SpectralPower, _ } +import squants.radio.{ Irradiance, RadiantIntensity, SpectralPower, WattsPerMeter, WattsPerSquareMeter, WattsPerSteradian } import squants.space.{ SolidAngle, SquareMeters, SquaredRadians } import squants.time.{ Hours, TimeDerivative, TimeIntegral } @@ -147,4 +147,3 @@ object PowerConversions { implicit object PowerNumeric extends AbstractQuantityNumeric[Power](Power.primaryUnit) } - diff --git a/shared/src/main/scala/squants/market/MoneyContext.scala b/shared/src/main/scala/squants/market/MoneyContext.scala index 0f61cbbf..651c7807 100644 --- a/shared/src/main/scala/squants/market/MoneyContext.scala +++ b/shared/src/main/scala/squants/market/MoneyContext.scala @@ -8,8 +8,6 @@ package squants.market -import scala.collection.SortedSet - /** * MoneyContext * diff --git a/shared/src/main/scala/squants/mass/AreaDensity.scala b/shared/src/main/scala/squants/mass/AreaDensity.scala index 95e6ee77..ec096992 100644 --- a/shared/src/main/scala/squants/mass/AreaDensity.scala +++ b/shared/src/main/scala/squants/mass/AreaDensity.scala @@ -9,7 +9,7 @@ package squants.mass import squants._ -import squants.space.{Acres, SquareMeters} +import squants.space.Acres /** * @author garyKeorkunian diff --git a/shared/src/main/scala/squants/motion/Acceleration.scala b/shared/src/main/scala/squants/motion/Acceleration.scala index dffa6413..6cb0e72a 100644 --- a/shared/src/main/scala/squants/motion/Acceleration.scala +++ b/shared/src/main/scala/squants/motion/Acceleration.scala @@ -10,7 +10,7 @@ package squants.motion import squants._ import squants.space.{ Feet, Millimeters, UsMiles } -import squants.time.{ Seconds, _ } +import squants.time.{ Seconds, TimeDerivative, TimeIntegral, SecondTimeDerivative, TimeSquared, Time } /** * Represents a quantity of acceleration diff --git a/shared/src/main/scala/squants/motion/Torque.scala b/shared/src/main/scala/squants/motion/Torque.scala index d28345f2..9b0fc3e9 100644 --- a/shared/src/main/scala/squants/motion/Torque.scala +++ b/shared/src/main/scala/squants/motion/Torque.scala @@ -1,8 +1,8 @@ package squants.motion -import squants.mass.{Kilograms, MomentOfInertia, Pounds} +import squants.mass.{MomentOfInertia, Pounds} import squants.space.{Feet, Meters} -import squants.{AbstractQuantityNumeric, Dimension, Energy, PrimaryUnit, Quantity, SiBaseUnit, UnitConverter, UnitOfMeasure} +import squants.{AbstractQuantityNumeric, Dimension, PrimaryUnit, Quantity, SiBaseUnit, UnitConverter, UnitOfMeasure} /** * @@ -58,4 +58,4 @@ object TorqueConversions { } implicit object TorqueNumeric extends AbstractQuantityNumeric[Torque](Torque.primaryUnit) -} \ No newline at end of file +} diff --git a/shared/src/main/tut/README.md b/shared/src/main/tut/README.md index c06dd905..fc404a0a 100644 --- a/shared/src/main/tut/README.md +++ b/shared/src/main/tut/README.md @@ -15,17 +15,17 @@ All types are immutable and thread-safe. | [![Join the chat at https://gitter.im/typelevel/squants](https://badges.gitter.im/typelevel/squants.svg)](https://gitter.im/typelevel/squants?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) | -[![Scaladocs](https://www.javadoc.io/badge/org.typelevel/squants_2.12.svg?label=scaladoc)](https://static.javadoc.io/org.typelevel/squants_2.12/1.2.0/squants/index.html) +[![Scaladocs](https://www.javadoc.io/badge/org.typelevel/squants_2.12.svg?label=scaladoc)](https://static.javadoc.io/org.typelevel/squants_2.12/1.4.0/squants/index.html) | [![Build Status](https://travis-ci.org/typelevel/squants.png?branch=master)](https://travis-ci.org/typelevel/squants) ### Current Versions -Current Release: **1.3.0** -([API Docs](https://oss.sonatype.org/service/local/repositories/releases/archive/org/typelevel/squants_2.11/1.3.0/squants_2.11-1.3.0-javadoc.jar/!/index.html#squants.package)) +Current Release: **1.4.0** +([API Docs](https://oss.sonatype.org/service/local/repositories/releases/archive/org/typelevel/squants_2.12/1.4.0/squants_2.12-1.4.0-javadoc.jar/!/index.html#squants.package)) -Development Build: **1.4.0-SNAPSHOT** -([API Docs](https://oss.sonatype.org/service/local/repositories/snapshots/archive/org/typelevel/squants_2.11/1.4.0-SNAPSHOT/squants_2.11-1.4.0-SNAPSHOT-javadoc.jar/!/index.html#squants.package)) +Development Build: **1.5.0-SNAPSHOT** +([API Docs](https://oss.sonatype.org/service/local/repositories/snapshots/archive/org/typelevel/squants_2.12/1.5.0-SNAPSHOT/squants_2.12-1.5.0-SNAPSHOT-javadoc.jar/!/index.html#squants.package)) [Release History](https://github.com/typelevel/squants/wiki/Release-History) @@ -38,10 +38,10 @@ For more information on feature availability of a specific version see the Relea Repository hosting for Squants is provided by [Sonatype](https://oss.sonatype.org/). To use Squants in your SBT project add the following dependency to your build. - "org.typelevel" %% "squants" % "1.3.0" + "org.typelevel" %% "squants" % "1.4.0" or - "org.typelevel" %% "squants" % "1.4.0-SNAPSHOT" + "org.typelevel" %% "squants" % "1.5.0-SNAPSHOT" To use Squants in your Maven project add the following dependency @@ -50,12 +50,13 @@ To use Squants in your Maven project add the following dependency org.typelevel squants_2.11 - 1.3.0 + 1.4.0 ``` Beginning with Squants 0.4.x series, both Scala 2.10 and 2.11 builds are available. Beginning with Squants 1.x series, Scala 2.10, 2.11 and 2.12 builds are available. +Scala.js is supported on version 0.6.25 and 1.0.0-M6 To use Squants interactively in the Scala REPL, clone the git repo and run `sbt squantsJVM/console` @@ -499,7 +500,7 @@ This will fail because `lower` = `upper`: QuantityRange(1.km, 1.km) ``` -`QuantityRange` contains two functions that check if an element is part of the range, `contains` and `includes`. +`QuantityRange` contains two functions that check if an element is part of the range, `contains` and `includes`. These differ in how they treat the range's upper bound: `contains()` _excludes_ it but `includes()` _includes_ it. ```tut @@ -532,7 +533,7 @@ val rs3 = range / Kilowatts(400) ### QuantityRange operations `QuantityRange` supports foreach, map, and foldLeft/foldRight. These vary slightly from the versions -in the Scala standard library in that they take a divisior as the first parameter. The examples below +in the Scala standard library in that they take a divisior as the first parameter. The examples below illustrate their use. Subdivide range into 1-Megawatt "slices", and foreach over each of slices: @@ -742,7 +743,7 @@ import squants.{Quantity, Dimension} import squants.space._ import squants.experimental.unitgroups.UnitGroup -val usCookingUnitGroup = new UnitGroup[Volume] { +val usCookingUnitGroup = new UnitGroup[Volume] { // units don't have to be specified in-order. val units: Set[UnitOfMeasure[Volume]] = Set(UsPints, UsGallons, Teaspoons, Tablespoons, UsQuarts, FluidOunces) } @@ -757,7 +758,7 @@ applicable. ## Formatters -Squants provides an experimental API for formatting Quantities in the "best unit." For example, +Squants provides an experimental API for formatting Quantities in the "best unit." For example, convert Inches(12) to Feet(1). This is useful for producing human-friendly output. To use a formatter, you must implement the `squants.formatters.Formatter` trait: @@ -770,7 +771,7 @@ trait Formatter[A <: Quantity[A]] { ### Default Formatter implementation -There is a default formatter implementation in `squants.experimental.formatter.DefaultFormatter`. This builds on the `UnitGroup` +There is a default formatter implementation in `squants.experimental.formatter.DefaultFormatter`. This builds on the `UnitGroup` API discussed above to choose the best `UnitOfMeasure` for a `Quantity`. The `DefaultFormatter` algorithm will probably work for most use-cases, but users can create their own `Formatters` if they have custom needs. @@ -823,7 +824,7 @@ import squants.experimental.unitgroups.misc.AstronomicalLengthUnitGroup ```tut:book implicit val astroFormatter = new DefaultFormatter(AstronomicalLengthUnitGroup) - + val earthToJupiter = 588000000.km val earthToVoyager1 = 2.06e10.km val earthToAlphaCentauri = 4.1315e+13.km @@ -841,7 +842,7 @@ This example won't compile because there is no `Formatter[Mass]` in implicit sco ### SI Formatters and implicit syntax -When using SI units, and the default formatter algorithm, you don't have to declare a `Formatter` and place it in +When using SI units, and the default formatter algorithm, you don't have to declare a `Formatter` and place it in implicit scope. The compiler can do that for you. This creates a very human-friendly API by using the appropriate imports. @@ -1204,6 +1205,11 @@ To make a release do the following: sbt squantsNative/publishSigned ``` +* Repeat for scala.js 1.0.0-M6 +``` + SCALAJS_VERSION=1.0.0-M6 sbt +squantsJS/publishSigned +``` + * Then make a release (Note: after this step the release cannot be replaced) ``` sbt sonatypeRelease diff --git a/shared/src/test/scala/squants/electro/ElectricChargeMassRatioSpec.scala b/shared/src/test/scala/squants/electro/ElectricChargeMassRatioSpec.scala index 63715a5c..ebcbeab8 100644 --- a/shared/src/test/scala/squants/electro/ElectricChargeMassRatioSpec.scala +++ b/shared/src/test/scala/squants/electro/ElectricChargeMassRatioSpec.scala @@ -3,7 +3,6 @@ package squants.electro import org.scalatest.{FlatSpec, Matchers} import squants.QuantityParseException import squants.mass.Kilograms -import squants.space.{CubicMeters, Meters, SquareMeters} /** * diff --git a/shared/src/test/scala/squants/electro/LinearElectricChargeDensitySpec.scala b/shared/src/test/scala/squants/electro/LinearElectricChargeDensitySpec.scala index 335944d3..b70ee9e6 100644 --- a/shared/src/test/scala/squants/electro/LinearElectricChargeDensitySpec.scala +++ b/shared/src/test/scala/squants/electro/LinearElectricChargeDensitySpec.scala @@ -2,7 +2,7 @@ package squants.electro import org.scalatest.{FlatSpec, Matchers} import squants.QuantityParseException -import squants.space.{CubicMeters, Meters, SquareMeters} +import squants.space.Meters /** * diff --git a/shared/src/test/scala/squants/electro/PermeabilitySpec.scala b/shared/src/test/scala/squants/electro/PermeabilitySpec.scala index d08ae137..bde22609 100644 --- a/shared/src/test/scala/squants/electro/PermeabilitySpec.scala +++ b/shared/src/test/scala/squants/electro/PermeabilitySpec.scala @@ -9,7 +9,7 @@ package squants.electro import org.scalatest.{FlatSpec, Matchers} -import squants.{MetricSystem, QuantityParseException} +import squants.QuantityParseException import squants.space.Meters /** diff --git a/shared/src/test/scala/squants/experimental/formatter/DefaultFormatterSpec.scala b/shared/src/test/scala/squants/experimental/formatter/DefaultFormatterSpec.scala index 8d878b2d..99bb4718 100644 --- a/shared/src/test/scala/squants/experimental/formatter/DefaultFormatterSpec.scala +++ b/shared/src/test/scala/squants/experimental/formatter/DefaultFormatterSpec.scala @@ -4,7 +4,7 @@ import org.scalatest.{FlatSpec, Matchers} import squants.UnitOfMeasure import squants.mass.{Kilograms, Mass} import squants.mass.MassConversions._ -import squants.space.{Inches, Length, Yards, UsMiles} +import squants.space.{Inches, Yards, UsMiles} import squants.space.LengthConversions._ import squants.experimental.unitgroups.UnitGroup import squants.experimental.unitgroups.uscustomary.space.UsCustomaryLengths diff --git a/shared/src/test/scala/squants/experimental/json/MoneySerializer.scala b/shared/src/test/scala/squants/experimental/json/MoneySerializer.scala index a3666d88..3f524b80 100644 --- a/shared/src/test/scala/squants/experimental/json/MoneySerializer.scala +++ b/shared/src/test/scala/squants/experimental/json/MoneySerializer.scala @@ -26,13 +26,13 @@ class MoneySerializer extends Serializer[Money] { def deserialize(implicit format: Formats) = { case (TypeInfo(money, _), json) if Clazz.isAssignableFrom(money) ⇒ json match { case JObject(List( - JField("amount", JDecimal(amount)), - JField("currency", JString(currency)))) ⇒ + JField("amount", JDecimal(_)), + JField("currency", JString(_)))) ⇒ val m = json.extract[MoneyData] Money(m.amount, m.currency) case JObject(List( - JField("amount", JInt(amount)), - JField("currency", JString(currency)))) ⇒ + JField("amount", JInt(_)), + JField("currency", JString(_)))) ⇒ val m = json.extract[MoneyData] Money(m.amount, m.currency) } @@ -46,4 +46,3 @@ class MoneySerializer extends Serializer[Money] { "currency" -> JString(money.unit.code))) } } - diff --git a/shared/src/test/scala/squants/market/MoneySpec.scala b/shared/src/test/scala/squants/market/MoneySpec.scala index eae4a235..410bc247 100644 --- a/shared/src/test/scala/squants/market/MoneySpec.scala +++ b/shared/src/test/scala/squants/market/MoneySpec.scala @@ -236,7 +236,7 @@ class MoneySpec extends FlatSpec with Matchers { } it should "return proper results when multiplying by Int" in { - val x: Int = 2 + val x: Double = 2 USD(10) * x should be(USD(20)) x * USD(10) * x should be(USD(40)) x * x * USD(10) should be(USD(40)) @@ -254,7 +254,7 @@ class MoneySpec extends FlatSpec with Matchers { it should "return proper results when multiplying by mix of BigDecimal, Double and Int" in { - val x: Int = 2 + val x: Double = 2 USD(10) * BigDecimal(2) should be(USD(20)) JPY(23.50) * BigDecimal(3) should be(JPY(70.50)) JPY(23.50) * BigDecimal(3) * 2 should be(JPY(141)) @@ -272,8 +272,8 @@ class MoneySpec extends FlatSpec with Matchers { } it should "return proper results when dividing by Int" in { - val x: Int = 2 - val y: Int = 3 + val x: Double = 2 + val y: Double = 3 USD(10) / x should be(USD(5)) JPY(75) / y should be(JPY(25)) (JPY(75) / y) / x should be(JPY(12.50)) diff --git a/shared/src/test/scala/squants/mass/MomentOfInertiaSpec.scala b/shared/src/test/scala/squants/mass/MomentOfInertiaSpec.scala index ad35c749..55226843 100644 --- a/shared/src/test/scala/squants/mass/MomentOfInertiaSpec.scala +++ b/shared/src/test/scala/squants/mass/MomentOfInertiaSpec.scala @@ -2,7 +2,7 @@ package squants.mass import org.scalatest.{FlatSpec, Matchers} import squants.CustomMatchers -import squants.motion.{AngularAccelerationConversions, NewtonMeters, RadiansPerSecondSquared} +import squants.motion.{NewtonMeters, RadiansPerSecondSquared} import squants.space.{Feet, Meters} /**