mirror of https://github.com/sbt/sbt.git
Merge pull request #807 from coursier/topic/less-scalaz
Remove scalaz dependency from core and cache
This commit is contained in:
commit
8cf4d7a16d
14
.travis.yml
14
.travis.yml
|
|
@ -1,6 +1,4 @@
|
|||
language: java
|
||||
install:
|
||||
- npm install
|
||||
os:
|
||||
- osx
|
||||
script:
|
||||
|
|
@ -18,13 +16,13 @@ matrix:
|
|||
- curl https://raw.githubusercontent.com/scala-native/scala-native/v0.3.6/bin/travis_setup.sh | bash -x
|
||||
services:
|
||||
- docker
|
||||
- env: SCALA_VERSION=2.11.11 PUBLISH=1
|
||||
- env: SCALA_VERSION=2.11.12 PUBLISH=1
|
||||
os: linux
|
||||
jdk: oraclejdk8
|
||||
sudo: required
|
||||
services:
|
||||
- docker
|
||||
- env: SCALA_VERSION=2.10.6 PUBLISH=1
|
||||
- env: SCALA_VERSION=2.10.7 PUBLISH=1
|
||||
os: linux
|
||||
jdk: oraclejdk8
|
||||
sudo: required
|
||||
|
|
@ -36,21 +34,21 @@ matrix:
|
|||
- env: SCALA_VERSION=2.12.4 SBT_SHADING=1
|
||||
os: linux
|
||||
jdk: oraclejdk8
|
||||
- env: SCALA_VERSION=2.10.6 SBT_COURSIER=1
|
||||
- env: SCALA_VERSION=2.10.7 SBT_COURSIER=1
|
||||
os: linux
|
||||
jdk: oraclejdk8
|
||||
services:
|
||||
- docker
|
||||
- env: SCALA_VERSION=2.10.6 SBT_SHADING=1
|
||||
- env: SCALA_VERSION=2.10.7 SBT_SHADING=1
|
||||
os: linux
|
||||
jdk: oraclejdk8
|
||||
- env: SCALA_VERSION=2.12.4 SCALA_JS=1
|
||||
os: linux
|
||||
jdk: oraclejdk8
|
||||
- env: SCALA_VERSION=2.11.11 SCALA_JS=1
|
||||
- env: SCALA_VERSION=2.11.12 SCALA_JS=1
|
||||
os: linux
|
||||
jdk: oraclejdk8
|
||||
- env: SCALA_VERSION=2.10.6 SCALA_JS=1
|
||||
- env: SCALA_VERSION=2.10.7 SCALA_JS=1
|
||||
os: linux
|
||||
jdk: oraclejdk8
|
||||
- os: linux
|
||||
|
|
|
|||
|
|
@ -90,14 +90,9 @@ $ sbt
|
|||
|
||||
## Run unit tests (JS)
|
||||
|
||||
The JS tests require node to be installed, and a few dependencies to have been
|
||||
fetched with
|
||||
```
|
||||
$ npm install
|
||||
```
|
||||
(run from the root of the coursier sources).
|
||||
The JS tests require node to be installed. They automatically run `npm install` from the root of the coursier sources if needed.
|
||||
|
||||
JS tests can then be run like JVM tests, like
|
||||
JS tests can be run like JVM tests, like
|
||||
```
|
||||
$ sbt
|
||||
> ++2.12.4
|
||||
|
|
@ -190,4 +185,4 @@ we need to put 2) and 3) into `message`:
|
|||
|
||||
Typically there needs to be at least 2 minor versions between since-version and to-be-removed-version to help migration.
|
||||
|
||||
For example, if since version is 1.1.0, then deprecation can be removed in 1.3.0
|
||||
For example, if since version is 1.1.0, then deprecation can be removed in 1.3.0
|
||||
|
|
|
|||
34
README.md
34
README.md
|
|
@ -160,17 +160,21 @@ val start = Resolution(
|
|||
|
||||
Create a fetch function able to get things from a few repositories via a local cache,
|
||||
```scala
|
||||
import coursier.util.Task
|
||||
|
||||
val repositories = Seq(
|
||||
Cache.ivy2Local,
|
||||
MavenRepository("https://repo1.maven.org/maven2")
|
||||
)
|
||||
|
||||
val fetch = Fetch.from(repositories, Cache.fetch())
|
||||
val fetch = Fetch.from(repositories, Cache.fetch[Task]())
|
||||
```
|
||||
|
||||
Then run the resolution per-se,
|
||||
```scala
|
||||
val resolution = start.process.run(fetch).unsafePerformSync
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
|
||||
val resolution = start.process.run(fetch).unsafeRun()
|
||||
```
|
||||
That will fetch and use metadata.
|
||||
|
||||
|
|
@ -183,11 +187,11 @@ These would mean that the resolution wasn't able to get metadata about some depe
|
|||
Then fetch and get local copies of the artifacts themselves (the JARs) with
|
||||
```scala
|
||||
import java.io.File
|
||||
import scalaz.concurrent.Task
|
||||
import coursier.util.Gather
|
||||
|
||||
val localArtifacts: Seq[Either[FileError, File]] = Task.gatherUnordered(
|
||||
resolution.artifacts.map(Cache.file(_).run)
|
||||
).unsafePerformSync
|
||||
val localArtifacts: Seq[Either[FileError, File]] = Gather[Task].gather(
|
||||
resolution.artifacts.map(Cache.file[Task](_).run)
|
||||
).unsafeRun()
|
||||
```
|
||||
|
||||
|
||||
|
|
@ -468,7 +472,7 @@ The resolution process will go on by giving successive `Resolution`s, until the
|
|||
`start` above is only the initial state - it is far from over, as the `isDone` method on it tells,
|
||||
```scala
|
||||
scala> start.isDone
|
||||
res4: Boolean = false
|
||||
res6: Boolean = false
|
||||
```
|
||||
|
||||
|
||||
|
|
@ -507,7 +511,7 @@ scala> MavenRepository(
|
|||
| "https://nexus.corp.com/content/repositories/releases",
|
||||
| authentication = Some(Authentication("user", "pass"))
|
||||
| )
|
||||
res6: coursier.maven.MavenRepository = MavenRepository(https://nexus.corp.com/content/repositories/releases,None,true,Some(Authentication(user, *******)))
|
||||
res8: coursier.maven.MavenRepository = MavenRepository(https://nexus.corp.com/content/repositories/releases,None,true,Some(Authentication(user, *******)))
|
||||
```
|
||||
|
||||
Now that we have repositories, we're going to mix these with things from the `coursier-cache` module,
|
||||
|
|
@ -517,7 +521,7 @@ Given a sequence of dependencies, designated by their `Module` (organisation and
|
|||
and version (just a `String`), it gives either errors (`Seq[String]`) or metadata (`(Artifact.Source, Project)`),
|
||||
wrapping the whole in a monad `F`.
|
||||
```scala
|
||||
val fetch = Fetch.from(repositories, Cache.fetch())
|
||||
val fetch = Fetch.from(repositories, Cache.fetch[Task]())
|
||||
```
|
||||
|
||||
The monad used by `Fetch.from` is `scalaz.concurrent.Task`, but the resolution process is not tied to a particular
|
||||
|
|
@ -543,7 +547,9 @@ resolution is particularly complex, in which case `maxIterations` could be incre
|
|||
|
||||
Let's run the whole resolution,
|
||||
```scala
|
||||
val resolution = start.process.run(fetch).unsafePerformSync
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
|
||||
val resolution = start.process.run(fetch).unsafeRun()
|
||||
```
|
||||
|
||||
To get additional feedback during the resolution, we can give the `Cache.default` method above
|
||||
|
|
@ -567,11 +573,11 @@ which are dependencies whose versions could not be unified.
|
|||
Then, if all went well, we can fetch and get local copies of the artifacts themselves (the JARs) with
|
||||
```scala
|
||||
import java.io.File
|
||||
import scalaz.concurrent.Task
|
||||
import coursier.util.Gather
|
||||
|
||||
val localArtifacts: Seq[Either[FileError, File]] = Task.gatherUnordered(
|
||||
resolution.artifacts.map(Cache.file(_).run)
|
||||
).unsafePerformSync
|
||||
val localArtifacts: Seq[Either[FileError, File]] = Gather[Task].gather(
|
||||
resolution.artifacts.map(Cache.file[Task](_).run)
|
||||
).unsafeRun()
|
||||
```
|
||||
|
||||
We're using the `Cache.file` method, that can also be given a `Logger` (for more feedback) and a custom thread pool.
|
||||
|
|
|
|||
14
appveyor.yml
14
appveyor.yml
|
|
@ -11,23 +11,23 @@ install:
|
|||
)
|
||||
[System.IO.Compression.ZipFile]::ExtractToDirectory("C:\sbt-bin.zip", "C:\sbt")
|
||||
}
|
||||
- cmd: SET JAVA_HOME=C:\Program Files\Java\jdk1.8.0
|
||||
- cmd: SET PATH=C:\sbt\sbt\bin;%JAVA_HOME%\bin;%PATH%
|
||||
- cmd: SET SBT_OPTS=-XX:MaxPermSize=2g -Xmx4g
|
||||
- git submodule update --init --recursive
|
||||
build_script:
|
||||
- sbt ++2.11.12 clean compile coreJVM/publishLocal
|
||||
- sbt ++2.10.6 clean compile
|
||||
- sbt ++2.12.4 coreJVM/publishLocal cache/publishLocal cli/publishLocal extra/publishLocal sbt-shared/publishLocal
|
||||
- sbt ++2.10.6 coreJVM/publishLocal cache/publishLocal extra/publishLocal sbt-shared/publishLocal
|
||||
- sbt ++2.10.7 clean compile
|
||||
- sbt ++2.12.4 coreJVM/publishLocal cacheJVM/publishLocal extra/publishLocal scalazJVM/publishLocal cli/publishLocal
|
||||
test_script:
|
||||
- ps: Start-Job -filepath .\scripts\start-it-auth-server.ps1 -ArgumentList $pwd
|
||||
- ps: Start-Sleep -s 15 # wait for the first server to have downloaded its dependencies
|
||||
- ps: Start-Job -filepath .\scripts\start-it-no-listing-server.ps1 -ArgumentList $pwd
|
||||
- sbt ++2.12.4 testsJVM/test testsJVM/it:test # Would node be around for testsJS/test?
|
||||
- sbt ++2.11.11 testsJVM/test testsJVM/it:test
|
||||
- sbt ++2.10.6 testsJVM/test testsJVM/it:test
|
||||
- sbt ++2.12.4 "sbt-coursier/scripted sbt-coursier/simple" sbt-coursier/publishLocal "sbt-shading/scripted sbt-shading/*" # for sbt 1.0
|
||||
- sbt ++2.10.6 "sbt-coursier/scripted sbt-coursier/*" "sbt-coursier/scripted sbt-coursier-0.13/*" sbt-coursier/publishLocal "sbt-shading/scripted sbt-shading/*" "sbt-shading/scripted sbt-shading-0.13/*" # for sbt 0.13
|
||||
- sbt ++2.11.12 testsJVM/test testsJVM/it:test
|
||||
- sbt ++2.10.7 testsJVM/test testsJVM/it:test
|
||||
- sbt ++2.12.4 "sbt-coursier/scripted sbt-coursier/simple" "sbt-shading/scripted sbt-shading/*" # for sbt 1.0
|
||||
- sbt ++2.10.7 "sbt-coursier/scripted sbt-coursier/*" "sbt-coursier/scripted sbt-coursier-0.13/*" "sbt-shading/scripted sbt-shading/*" "sbt-shading/scripted sbt-shading-0.13/*" # for sbt 0.13
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
|
|
|
|||
123
build.sbt
123
build.sbt
|
|
@ -30,7 +30,6 @@ lazy val core = crossProject
|
|||
.settings(
|
||||
shared,
|
||||
name := "coursier",
|
||||
libs += CrossDeps.scalazCore.value,
|
||||
Mima.previousArtifacts,
|
||||
Mima.coreFilters
|
||||
)
|
||||
|
|
@ -38,23 +37,12 @@ lazy val core = crossProject
|
|||
lazy val coreJvm = core.jvm
|
||||
lazy val coreJs = core.js
|
||||
|
||||
lazy val `fetch-js` = project
|
||||
.disablePlugins(ScriptedPlugin)
|
||||
.enablePlugins(ScalaJSPlugin)
|
||||
.dependsOn(coreJs)
|
||||
.settings(
|
||||
shared,
|
||||
dontPublish,
|
||||
coursierPrefix
|
||||
)
|
||||
|
||||
lazy val tests = crossProject
|
||||
.disablePlugins(ScriptedPlugin)
|
||||
.dependsOn(core)
|
||||
.jvmConfigure(_.dependsOn(cache % "test"))
|
||||
.jsConfigure(_.dependsOn(`fetch-js` % "test"))
|
||||
.dependsOn(core, cache % "test", scalaz)
|
||||
.jsSettings(
|
||||
scalaJSStage.in(Global) := FastOptStage
|
||||
scalaJSStage.in(Global) := FastOptStage,
|
||||
testOptions := testOptions.dependsOn(runNpmInstallIfNeeded).value
|
||||
)
|
||||
.configs(Integration)
|
||||
.settings(
|
||||
|
|
@ -92,18 +80,44 @@ lazy val paths = project
|
|||
addDirectoriesSources
|
||||
)
|
||||
|
||||
lazy val cache = project
|
||||
lazy val cache = crossProject
|
||||
.disablePlugins(ScriptedPlugin)
|
||||
.dependsOn(coreJvm)
|
||||
.dependsOn(core)
|
||||
.jvmSettings(
|
||||
addPathsSources
|
||||
)
|
||||
.jsSettings(
|
||||
name := "fetch-js"
|
||||
)
|
||||
.settings(
|
||||
shared,
|
||||
Mima.previousArtifacts,
|
||||
coursierPrefix,
|
||||
libs += Deps.scalazConcurrent,
|
||||
Mima.cacheFilters,
|
||||
addPathsSources
|
||||
Mima.cacheFilters
|
||||
)
|
||||
|
||||
lazy val cacheJvm = cache.jvm
|
||||
lazy val cacheJs = cache.js
|
||||
|
||||
lazy val scalaz = crossProject
|
||||
.disablePlugins(ScriptedPlugin)
|
||||
.dependsOn(cache)
|
||||
.jvmSettings(
|
||||
libs += Deps.scalazConcurrent
|
||||
)
|
||||
.jsSettings(
|
||||
libs += CrossDeps.scalazCore.value
|
||||
)
|
||||
.settings(
|
||||
name := "scalaz-interop",
|
||||
shared,
|
||||
Mima.previousArtifacts,
|
||||
coursierPrefix
|
||||
)
|
||||
|
||||
lazy val scalazJvm = scalaz.jvm
|
||||
lazy val scalazJs = scalaz.js
|
||||
|
||||
lazy val bootstrap = project
|
||||
.disablePlugins(ScriptedPlugin)
|
||||
.settings(
|
||||
|
|
@ -118,7 +132,7 @@ lazy val bootstrap = project
|
|||
lazy val extra = project
|
||||
.disablePlugins(ScriptedPlugin)
|
||||
.enablePlugins(ShadingPlugin)
|
||||
.dependsOn(coreJvm, cache)
|
||||
.dependsOn(coreJvm, cacheJvm)
|
||||
.settings(
|
||||
shared,
|
||||
coursierPrefix,
|
||||
|
|
@ -150,7 +164,7 @@ lazy val extra = project
|
|||
)
|
||||
|
||||
lazy val cli = project
|
||||
.dependsOn(coreJvm, cache, extra)
|
||||
.dependsOn(coreJvm, cacheJvm, extra, scalazJvm)
|
||||
.disablePlugins(ScriptedPlugin)
|
||||
.enablePlugins(PackPlugin, SbtProguard)
|
||||
.settings(
|
||||
|
|
@ -182,7 +196,7 @@ lazy val cli = project
|
|||
lazy val web = project
|
||||
.disablePlugins(ScriptedPlugin)
|
||||
.enablePlugins(ScalaJSPlugin)
|
||||
.dependsOn(coreJs, `fetch-js`)
|
||||
.dependsOn(coreJs, cacheJs)
|
||||
.settings(
|
||||
shared,
|
||||
dontPublish,
|
||||
|
|
@ -227,7 +241,7 @@ lazy val web = project
|
|||
|
||||
lazy val readme = project
|
||||
.in(file("doc/readme"))
|
||||
.dependsOn(coreJvm, cache)
|
||||
.dependsOn(coreJvm, cacheJvm, scalazJvm)
|
||||
.disablePlugins(ScriptedPlugin)
|
||||
.enablePlugins(TutPlugin)
|
||||
.settings(
|
||||
|
|
@ -238,7 +252,7 @@ lazy val readme = project
|
|||
)
|
||||
|
||||
lazy val `sbt-shared` = project
|
||||
.dependsOn(coreJvm, cache)
|
||||
.dependsOn(coreJvm, cacheJvm)
|
||||
.disablePlugins(ScriptedPlugin)
|
||||
.settings(
|
||||
plugin,
|
||||
|
|
@ -259,11 +273,22 @@ lazy val `sbt-shared` = project
|
|||
)
|
||||
|
||||
lazy val `sbt-coursier` = project
|
||||
.dependsOn(coreJvm, cache, extra, `sbt-shared`)
|
||||
.dependsOn(coreJvm, cacheJvm, extra, `sbt-shared`, scalazJvm)
|
||||
.disablePlugins(ScriptedPlugin)
|
||||
.settings(
|
||||
plugin,
|
||||
utest
|
||||
utest,
|
||||
scriptedDependencies := {
|
||||
scriptedDependencies.value
|
||||
|
||||
// TODO Get dependency projects automatically
|
||||
// (but shouldn't scripted itself handle that…?)
|
||||
publishLocal.in(coreJvm).value
|
||||
publishLocal.in(cacheJvm).value
|
||||
publishLocal.in(extra).value
|
||||
publishLocal.in(`sbt-shared`).value
|
||||
publishLocal.in(scalazJvm).value
|
||||
}
|
||||
)
|
||||
|
||||
lazy val `sbt-pgp-coursier` = project
|
||||
|
|
@ -277,6 +302,11 @@ lazy val `sbt-pgp-coursier` = project
|
|||
Seq(Deps.sbtPgp.value)
|
||||
case _ => Nil
|
||||
}
|
||||
},
|
||||
scriptedDependencies := {
|
||||
scriptedDependencies.value
|
||||
// TODO Get dependency projects automatically
|
||||
scriptedDependencies.in(`sbt-coursier`).value
|
||||
}
|
||||
)
|
||||
|
||||
|
|
@ -290,11 +320,16 @@ lazy val `sbt-shading` = project
|
|||
localM2Repository, // for a possibly locally published jarjar
|
||||
libs += Deps.jarjar % "shaded",
|
||||
// dependencies of jarjar-core - directly depending on these so that they don't get shaded
|
||||
libs ++= Deps.jarjarTransitiveDeps
|
||||
libs ++= Deps.jarjarTransitiveDeps,
|
||||
scriptedDependencies := {
|
||||
scriptedDependencies.value
|
||||
// TODO Get dependency projects automatically
|
||||
scriptedDependencies.in(`sbt-coursier`).value
|
||||
}
|
||||
)
|
||||
|
||||
lazy val okhttp = project
|
||||
.dependsOn(cache)
|
||||
.dependsOn(cacheJvm)
|
||||
.disablePlugins(ScriptedPlugin)
|
||||
.settings(
|
||||
shared,
|
||||
|
|
@ -310,7 +345,8 @@ lazy val jvm = project
|
|||
testsJvm,
|
||||
`proxy-tests`,
|
||||
paths,
|
||||
cache,
|
||||
cacheJvm,
|
||||
scalazJvm,
|
||||
bootstrap,
|
||||
extra,
|
||||
cli,
|
||||
|
|
@ -332,7 +368,7 @@ lazy val js = project
|
|||
.disablePlugins(ScriptedPlugin)
|
||||
.aggregate(
|
||||
coreJs,
|
||||
`fetch-js`,
|
||||
cacheJs,
|
||||
testsJs,
|
||||
web
|
||||
)
|
||||
|
|
@ -342,37 +378,18 @@ lazy val js = project
|
|||
moduleName := "coursier-js"
|
||||
)
|
||||
|
||||
// run sbt-plugins/publishLocal to publish all that necessary for plugins
|
||||
lazy val `sbt-plugins` = project
|
||||
.dummy
|
||||
.disablePlugins(ScriptedPlugin)
|
||||
.aggregate(
|
||||
coreJvm,
|
||||
cache,
|
||||
extra,
|
||||
`sbt-shared`,
|
||||
`sbt-coursier`,
|
||||
`sbt-pgp-coursier`,
|
||||
`sbt-shading`
|
||||
)
|
||||
.settings(
|
||||
shared,
|
||||
pluginOverrideCrossScalaVersion,
|
||||
dontPublish
|
||||
)
|
||||
|
||||
lazy val coursier = project
|
||||
.in(root)
|
||||
.disablePlugins(ScriptedPlugin)
|
||||
.aggregate(
|
||||
coreJvm,
|
||||
coreJs,
|
||||
`fetch-js`,
|
||||
testsJvm,
|
||||
testsJs,
|
||||
`proxy-tests`,
|
||||
paths,
|
||||
cache,
|
||||
cacheJvm,
|
||||
cacheJs,
|
||||
bootstrap,
|
||||
extra,
|
||||
cli,
|
||||
|
|
@ -380,6 +397,8 @@ lazy val coursier = project
|
|||
`sbt-coursier`,
|
||||
`sbt-pgp-coursier`,
|
||||
`sbt-shading`,
|
||||
scalazJvm,
|
||||
scalazJs,
|
||||
web,
|
||||
readme,
|
||||
okhttp
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@ scala_library(
|
|||
name = "cache",
|
||||
dependencies = [
|
||||
"core:core",
|
||||
"3rdparty/jvm:scalaz-concurrent",
|
||||
"paths/src/main/java:paths",
|
||||
],
|
||||
sources = rglobs("*.scala"),
|
||||
sources = rglobs("jvm/*.scala", "shared/*.scala"),
|
||||
)
|
||||
|
|
@ -1,10 +1,9 @@
|
|||
package coursier
|
||||
|
||||
import coursier.util.EitherT
|
||||
import coursier.util.{EitherT, Task}
|
||||
import org.scalajs.dom.raw.{Event, XMLHttpRequest}
|
||||
|
||||
import scala.concurrent.{ExecutionContext, Future, Promise}
|
||||
import scala.language.implicitConversions
|
||||
import scala.scalajs.js
|
||||
import js.Dynamic.{global => g}
|
||||
import scala.scalajs.js.timers._
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package coursier.util
|
||||
|
||||
abstract class PlatformTask {
|
||||
|
||||
implicit val gather: Gather[Task] =
|
||||
new TaskGather {}
|
||||
|
||||
}
|
||||
|
|
@ -10,11 +10,12 @@ import java.util.regex.Pattern
|
|||
import coursier.core.Authentication
|
||||
import coursier.ivy.IvyRepository
|
||||
import coursier.internal.FileUtil
|
||||
import coursier.util.Base64.Encoder
|
||||
|
||||
import scala.annotation.tailrec
|
||||
import java.io.{Serializable => _, _}
|
||||
import java.nio.charset.Charset
|
||||
import java.nio.charset.StandardCharsets.UTF_8
|
||||
import java.nio.file.{Files, StandardCopyOption}
|
||||
import java.util.Base64
|
||||
|
||||
import coursier.util.{EitherT, Schedulable}
|
||||
|
||||
|
|
@ -34,9 +35,6 @@ object Cache {
|
|||
}
|
||||
}
|
||||
|
||||
// java.nio.charset.StandardCharsets.UTF_8 not available in Java 6
|
||||
private val UTF_8 = Charset.forName("UTF-8")
|
||||
|
||||
// Check SHA-1 if available, else be fine with no checksum
|
||||
val defaultChecksums = Seq(Some("SHA-1"), None)
|
||||
|
||||
|
|
@ -268,7 +266,9 @@ object Cache {
|
|||
).r
|
||||
|
||||
private def basicAuthenticationEncode(user: String, password: String): String =
|
||||
(user + ":" + password).getBytes(UTF_8).toBase64
|
||||
Base64.getEncoder.encodeToString(
|
||||
s"$user:$password".getBytes(UTF_8)
|
||||
)
|
||||
|
||||
/**
|
||||
* Returns a `java.net.URL` for `s`, possibly using the custom protocol handlers found under the
|
||||
|
|
@ -334,9 +334,8 @@ object Cache {
|
|||
var success = false
|
||||
try {
|
||||
c.setRequestMethod("HEAD")
|
||||
val len = Some(c.getContentLength) // TODO Use getContentLengthLong when switching to Java >= 7
|
||||
.filter(_ >= 0)
|
||||
.map(_.toLong)
|
||||
val len = Some(c.getContentLengthLong)
|
||||
.filter(_ >= 0L)
|
||||
|
||||
// TODO 404 Not found could be checked here
|
||||
|
||||
|
|
@ -581,8 +580,7 @@ object Cache {
|
|||
else if (responseCode(conn) == Some(401))
|
||||
Left(FileError.Unauthorized(url, realm = realm(conn)))
|
||||
else {
|
||||
// TODO Use the safer getContentLengthLong when switching back to Java >= 7
|
||||
for (len0 <- Option(conn.getContentLength) if len0 >= 0L) {
|
||||
for (len0 <- Option(conn.getContentLengthLong) if len0 >= 0L) {
|
||||
val len = len0 + (if (partialDownload) alreadyDownloaded else 0L)
|
||||
logger.foreach(_.downloadLength(url, len, alreadyDownloaded, watching = false))
|
||||
}
|
||||
|
|
@ -601,7 +599,7 @@ object Cache {
|
|||
|
||||
withStructureLock(cache) {
|
||||
file.getParentFile.mkdirs()
|
||||
FileUtil.atomicMove(tmp, file)
|
||||
Files.move(tmp.toPath, file.toPath, StandardCopyOption.ATOMIC_MOVE)
|
||||
}
|
||||
|
||||
for (lastModified <- Option(conn.getLastModified) if lastModified > 0L)
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
package coursier.internal
|
||||
|
||||
import java.io.{ByteArrayOutputStream, File, FileInputStream, FileOutputStream, InputStream}
|
||||
import java.nio.file.Files
|
||||
|
||||
object FileUtil {
|
||||
|
||||
def write(file: File, bytes: Array[Byte]): Unit = {
|
||||
var fos: FileOutputStream = null
|
||||
try {
|
||||
fos = new FileOutputStream(file)
|
||||
fos.write(bytes)
|
||||
fos.close()
|
||||
} finally {
|
||||
if (fos != null) fos.close()
|
||||
}
|
||||
}
|
||||
|
||||
def readFully(is: InputStream): Array[Byte] = {
|
||||
val buffer = new ByteArrayOutputStream
|
||||
val data = Array.ofDim[Byte](16384)
|
||||
|
||||
var nRead = 0
|
||||
while ({
|
||||
nRead = is.read(data, 0, data.length)
|
||||
nRead != -1
|
||||
})
|
||||
buffer.write(data, 0, nRead)
|
||||
|
||||
buffer.flush()
|
||||
buffer.toByteArray
|
||||
}
|
||||
|
||||
def readAllBytes(file: File): Array[Byte] = {
|
||||
var fis: FileInputStream = null
|
||||
try {
|
||||
fis = new FileInputStream(file)
|
||||
readFully(fis)
|
||||
} finally {
|
||||
if (fis != null)
|
||||
fis.close()
|
||||
}
|
||||
}
|
||||
|
||||
def createTempDirectory(prefix: String): File =
|
||||
Files.createTempDirectory(prefix).toFile
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package coursier.util
|
||||
|
||||
import java.util.concurrent.ExecutorService
|
||||
|
||||
import scala.concurrent.{Await, ExecutionContext, ExecutionContextExecutorService, Future}
|
||||
import scala.concurrent.duration.Duration
|
||||
|
||||
abstract class PlatformTask { self =>
|
||||
|
||||
def schedule[A](pool: ExecutorService)(f: => A): Task[A] = {
|
||||
|
||||
val ec0 = pool match {
|
||||
case eces: ExecutionContextExecutorService => eces
|
||||
case _ => ExecutionContext.fromExecutorService(pool) // FIXME Is this instantiation costly? Cache it?
|
||||
}
|
||||
|
||||
Task(_ => Future(f)(ec0))
|
||||
}
|
||||
|
||||
implicit val schedulable: Schedulable[Task] =
|
||||
new TaskGather with Schedulable[Task] {
|
||||
def schedule[A](pool: ExecutorService)(f: => A) = self.schedule(pool)(f)
|
||||
}
|
||||
|
||||
def gather: Gather[Task] =
|
||||
schedulable
|
||||
|
||||
implicit class PlatformTaskOps[T](private val task: Task[T]) {
|
||||
def unsafeRun()(implicit ec: ExecutionContext): T =
|
||||
Await.result(task.future(), Duration.Inf)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -2,28 +2,14 @@ package coursier.util
|
|||
|
||||
import java.util.concurrent.{ExecutorService, Executors, ThreadFactory}
|
||||
|
||||
import scala.language.higherKinds
|
||||
import scalaz.concurrent.{Task => ScalazTask}
|
||||
|
||||
trait Schedulable[F[_]] extends Gather[F] {
|
||||
def schedule[A](pool: ExecutorService)(f: => A): F[A]
|
||||
}
|
||||
|
||||
object Schedulable {
|
||||
|
||||
implicit val scalazTask: Schedulable[ScalazTask] =
|
||||
new Schedulable[ScalazTask] {
|
||||
def point[A](a: A) =
|
||||
ScalazTask.point(a)
|
||||
def schedule[A](pool: ExecutorService)(f: => A) =
|
||||
ScalazTask(f)(pool)
|
||||
|
||||
def gather[A](elems: Seq[ScalazTask[A]]) =
|
||||
ScalazTask.taskInstance.gather(elems)
|
||||
|
||||
def bind[A, B](elem: ScalazTask[A])(f: A => ScalazTask[B]) =
|
||||
ScalazTask.taskInstance.bind(elem)(f)
|
||||
}
|
||||
lazy val defaultThreadPool =
|
||||
fixedThreadPool(4 max Runtime.getRuntime.availableProcessors())
|
||||
|
||||
def fixedThreadPool(size: Int): ExecutorService =
|
||||
Executors.newFixedThreadPool(
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package coursier.util
|
||||
|
||||
import scala.concurrent.{ExecutionContext, Future, Promise}
|
||||
|
||||
final case class Task[T](value: ExecutionContext => Future[T]) extends AnyVal {
|
||||
|
||||
def map[U](f: T => U): Task[U] =
|
||||
Task(implicit ec => value(ec).map(f))
|
||||
def flatMap[U](f: T => Task[U]): Task[U] =
|
||||
Task(implicit ec => value(ec).flatMap(t => f(t).value(ec)))
|
||||
|
||||
def handle[U >: T](f: PartialFunction[Throwable, U]): Task[U] =
|
||||
Task(ec => value(ec).recover(f)(ec))
|
||||
|
||||
def future()(implicit ec: ExecutionContext): Future[T] =
|
||||
value(ec)
|
||||
}
|
||||
|
||||
object Task extends PlatformTask {
|
||||
|
||||
def point[A](a: A): Task[A] = {
|
||||
val future = Future.successful(a)
|
||||
Task(_ => future)
|
||||
}
|
||||
|
||||
def delay[A](a: => A): Task[A] =
|
||||
Task(ec => Future(a)(ec))
|
||||
|
||||
def never[A]: Task[A] =
|
||||
Task(_ => Promise[A].future)
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package coursier.util
|
||||
|
||||
import scala.concurrent.Future
|
||||
|
||||
trait TaskGather extends Gather[Task] {
|
||||
def point[A](a: A) = Task.point(a)
|
||||
def bind[A, B](elem: Task[A])(f: A => Task[B]) =
|
||||
elem.flatMap(f)
|
||||
|
||||
def gather[A](elems: Seq[Task[A]]) =
|
||||
Task(implicit ec => Future.sequence(elems.map(_.value(ec))))
|
||||
}
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
package coursier.internal
|
||||
|
||||
import java.io._
|
||||
import java.util.UUID
|
||||
|
||||
/** Java 6-compatible helpers mimicking NIO */
|
||||
object FileUtil {
|
||||
|
||||
private object Java7 {
|
||||
|
||||
import java.nio.file.{ Files, StandardCopyOption }
|
||||
|
||||
def atomicMove(from: File, to: File): Unit =
|
||||
Files.move(from.toPath, to.toPath, StandardCopyOption.ATOMIC_MOVE)
|
||||
|
||||
def createTempDirectory(prefix: String): File =
|
||||
Files.createTempDirectory(prefix).toFile
|
||||
}
|
||||
|
||||
private object Java6 {
|
||||
def move(from: File, to: File): Unit =
|
||||
if (!from.renameTo(to))
|
||||
throw new IOException(s"Cannot move $from to $to")
|
||||
|
||||
def createTempDirectory(prefix: String): File = {
|
||||
val tmpBaseDir = new File(sys.props("java.io.tmpdir"))
|
||||
val tmpDir = new File(tmpBaseDir, s"$prefix-${UUID.randomUUID()}")
|
||||
tmpDir.mkdirs()
|
||||
tmpDir
|
||||
}
|
||||
}
|
||||
|
||||
private def versionGteq(version: String, to: (Int, Int)): Boolean =
|
||||
version.split('.').take(2).map(s => scala.util.Try(s.toInt).toOption) match {
|
||||
case Array(Some(major), Some(minor)) =>
|
||||
Ordering[(Int, Int)].gteq((major, minor), (1, 7))
|
||||
case _ => false
|
||||
}
|
||||
|
||||
// Fine if set several times (if java7Available() is initially called concurrently)
|
||||
@volatile private var java7AvailableOpt = Option.empty[Boolean]
|
||||
private def java7Available(): Boolean =
|
||||
java7AvailableOpt.getOrElse {
|
||||
val available = sys.props.get("java.version").exists { version =>
|
||||
versionGteq(version, (1, 7))
|
||||
}
|
||||
java7AvailableOpt = Some(available)
|
||||
available
|
||||
}
|
||||
|
||||
/** Not guaranteed to be atomic on Java 6 */
|
||||
def atomicMove(from: File, to: File): Unit =
|
||||
if (java7Available())
|
||||
Java7.atomicMove(from, to)
|
||||
else
|
||||
Java6.move(from, to)
|
||||
|
||||
def write(file: File, bytes: Array[Byte]): Unit = {
|
||||
var fos: FileOutputStream = null
|
||||
try {
|
||||
fos = new FileOutputStream(file)
|
||||
fos.write(bytes)
|
||||
fos.close()
|
||||
} finally {
|
||||
if (fos != null) fos.close()
|
||||
}
|
||||
}
|
||||
|
||||
def readFully(is: InputStream): Array[Byte] = {
|
||||
val buffer = new ByteArrayOutputStream
|
||||
val data = Array.ofDim[Byte](16384)
|
||||
|
||||
var nRead = 0
|
||||
while ({
|
||||
nRead = is.read(data, 0, data.length)
|
||||
nRead != -1
|
||||
})
|
||||
buffer.write(data, 0, nRead)
|
||||
|
||||
buffer.flush()
|
||||
buffer.toByteArray
|
||||
}
|
||||
|
||||
def readAllBytes(file: File): Array[Byte] = {
|
||||
var fis: FileInputStream = null
|
||||
try {
|
||||
fis = new FileInputStream(file)
|
||||
readFully(fis)
|
||||
} finally {
|
||||
if (fis != null)
|
||||
fis.close()
|
||||
}
|
||||
}
|
||||
|
||||
def createTempDirectory(prefix: String): File =
|
||||
if (java7Available())
|
||||
Java7.createTempDirectory(prefix)
|
||||
else
|
||||
Java6.createTempDirectory(prefix)
|
||||
|
||||
}
|
||||
|
|
@ -1,106 +0,0 @@
|
|||
package coursier.util
|
||||
|
||||
import scala.collection.mutable.ArrayBuilder
|
||||
|
||||
/**
|
||||
* Base64 encoder
|
||||
* @author Mark Lister
|
||||
* This software is distributed under the 2-Clause BSD license. See the
|
||||
* LICENSE file in the root of the repository.
|
||||
*
|
||||
* Copyright (c) 2014 - 2015 Mark Lister
|
||||
*
|
||||
* The repo for this Base64 encoder lives at https://github.com/marklister/base64
|
||||
* Please send your issues, suggestions and pull requests there.
|
||||
*/
|
||||
|
||||
object Base64 {
|
||||
|
||||
final case class B64Scheme(encodeTable: Array[Char], strictPadding: Boolean = true,
|
||||
postEncode: String => String = identity,
|
||||
preDecode: String => String = identity) {
|
||||
lazy val decodeTable = {
|
||||
val b: Array[Int] = new Array[Int](256)
|
||||
for (x <- encodeTable.zipWithIndex) {
|
||||
b(x._1) = x._2.toInt
|
||||
}
|
||||
b
|
||||
}
|
||||
}
|
||||
|
||||
val base64 = new B64Scheme((('A' to 'Z') ++ ('a' to 'z') ++ ('0' to '9') ++ Seq('+', '/')).toArray)
|
||||
val base64Url = new B64Scheme(base64.encodeTable.dropRight(2) ++ Seq('-', '_'), false,
|
||||
_.replaceAllLiterally("=", "%3D"),
|
||||
_.replaceAllLiterally("%3D", "="))
|
||||
|
||||
implicit class SeqEncoder(s: Seq[Byte]) {
|
||||
def toBase64(implicit scheme: B64Scheme = base64): String = Encoder(s.toArray).toBase64
|
||||
}
|
||||
|
||||
implicit class Encoder(b: Array[Byte]) {
|
||||
val r = new StringBuilder((b.length + 3) * 4 / 3)
|
||||
lazy val pad = (3 - b.length % 3) % 3
|
||||
|
||||
def toBase64(implicit scheme: B64Scheme = base64): String = {
|
||||
def sixBits(x: Byte, y: Byte, z: Byte): Unit = {
|
||||
val zz = (x & 0xff) << 16 | (y & 0xff) << 8 | (z & 0xff)
|
||||
r += scheme.encodeTable(zz >> 18)
|
||||
r += scheme.encodeTable(zz >> 12 & 0x3f)
|
||||
r += scheme.encodeTable(zz >> 6 & 0x3f)
|
||||
r += scheme.encodeTable(zz & 0x3f)
|
||||
}
|
||||
for (p <- 0 until b.length - 2 by 3) {
|
||||
sixBits(b(p), b(p + 1), b(p + 2))
|
||||
}
|
||||
pad match {
|
||||
case 0 =>
|
||||
case 1 => sixBits(b(b.length - 2), b(b.length - 1), 0)
|
||||
case 2 => sixBits(b(b.length - 1), 0, 0)
|
||||
}
|
||||
r.length = (r.length - pad)
|
||||
r ++= "=" * pad
|
||||
scheme.postEncode(r.toString())
|
||||
}
|
||||
}
|
||||
|
||||
implicit class Decoder(s: String) {
|
||||
|
||||
def toByteArray(implicit scheme: B64Scheme = base64): Array[Byte] = {
|
||||
val pre = scheme.preDecode(s)
|
||||
val cleanS = pre.replaceAll("=+$", "")
|
||||
val pad = pre.length - cleanS.length
|
||||
val computedPad = (4 - (cleanS.length % 4)) % 4
|
||||
val r = new ArrayBuilder.ofByte
|
||||
|
||||
def threeBytes(a: Int, b: Int, c: Int, d: Int): Unit = {
|
||||
val i = a << 18 | b << 12 | c << 6 | d
|
||||
r += ((i >> 16).toByte)
|
||||
r += ((i >> 8).toByte)
|
||||
r += (i.toByte)
|
||||
}
|
||||
if (scheme.strictPadding) {
|
||||
if (pad > 2) throw new java.lang.IllegalArgumentException("Invalid Base64 String: (excessive padding) " + s)
|
||||
if (s.length % 4 != 0) throw new java.lang.IllegalArgumentException("Invalid Base64 String: (padding problem) " + s)
|
||||
}
|
||||
if (computedPad == 3) throw new java.lang.IllegalArgumentException("Invalid Base64 String: (string length) " + s)
|
||||
try {
|
||||
val s = (cleanS + "A" * computedPad)
|
||||
for (x <- 0 until s.length - 1 by 4) {
|
||||
val i = scheme.decodeTable(s.charAt(x)) << 18 |
|
||||
scheme.decodeTable(s.charAt(x + 1)) << 12 |
|
||||
scheme.decodeTable(s.charAt(x + 2)) << 6 |
|
||||
scheme.decodeTable(s.charAt(x + 3))
|
||||
r += ((i >> 16).toByte)
|
||||
r += ((i >> 8).toByte)
|
||||
r += (i.toByte)
|
||||
}
|
||||
} catch {
|
||||
case e: NoSuchElementException => throw new java.lang.IllegalArgumentException("Invalid Base64 String: (invalid character)" + e.getMessage + s)
|
||||
}
|
||||
val res = r.result
|
||||
res.slice(0, res.length - computedPad)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -3,11 +3,12 @@ scala_library(
|
|||
dependencies = [
|
||||
"3rdparty/jvm:argonaut-shapeless",
|
||||
"3rdparty/jvm:caseapp",
|
||||
"cache/src/main/scala:cache",
|
||||
"cache:cache",
|
||||
"core:core",
|
||||
"extra/src/main/scala/coursier:fallback-deps-repo",
|
||||
"extra/src/main/scala/coursier/extra:extra",
|
||||
"extra/src/main/scala-2.12/coursier/extra:native",
|
||||
"scalaz:scalaz-interop",
|
||||
":util",
|
||||
],
|
||||
sources = globs(
|
||||
|
|
@ -22,7 +23,7 @@ scala_library(
|
|||
name = "util",
|
||||
dependencies = [
|
||||
"3rdparty/jvm:argonaut-shapeless",
|
||||
"cache/src/main/scala:cache",
|
||||
"cache:cache",
|
||||
"core:core",
|
||||
],
|
||||
sources = globs("coursier/cli/util/*.scala"),
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package coursier
|
|||
package cli
|
||||
|
||||
import java.io.{ByteArrayInputStream, ByteArrayOutputStream, File, FileInputStream, IOException}
|
||||
import java.nio.charset.StandardCharsets.UTF_8
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.attribute.PosixFilePermission
|
||||
import java.util.Properties
|
||||
|
|
@ -156,7 +157,7 @@ object Bootstrap extends CaseApp[BootstrapOptions] {
|
|||
entry.setTime(time)
|
||||
|
||||
outputZip.putNextEntry(entry)
|
||||
outputZip.write(content.getBytes("UTF-8"))
|
||||
outputZip.write(content.getBytes(UTF_8))
|
||||
outputZip.closeEntry()
|
||||
}
|
||||
|
||||
|
|
@ -207,7 +208,7 @@ object Bootstrap extends CaseApp[BootstrapOptions] {
|
|||
"exec java -jar " + options.options.javaOpt.map(s => "'" + s.replace("'", "\\'") + "'").mkString(" ") + " \"$0\" \"$@\""
|
||||
).mkString("", "\n", "\n")
|
||||
|
||||
try FileUtil.write(output0, shellPreamble.getBytes("UTF-8") ++ buffer.toByteArray)
|
||||
try FileUtil.write(output0, shellPreamble.getBytes(UTF_8) ++ buffer.toByteArray)
|
||||
catch { case e: IOException =>
|
||||
Console.err.println(s"Error while writing $output0${Option(e.getMessage).fold("")(" (" + _ + ")")}")
|
||||
sys.exit(1)
|
||||
|
|
|
|||
|
|
@ -6,8 +6,6 @@ import java.io.File
|
|||
import caseapp._
|
||||
import coursier.cli.options.FetchOptions
|
||||
|
||||
import scala.language.reflectiveCalls
|
||||
|
||||
final class Fetch(options: FetchOptions, args: RemainingArgs) {
|
||||
|
||||
val helper = new Helper(options.common, args.all, ignoreErrors = options.artifactOptions.force)
|
||||
|
|
|
|||
|
|
@ -10,14 +10,14 @@ import coursier.cli.options.{CommonOptions, IsolatedLoaderOptions}
|
|||
import coursier.cli.scaladex.Scaladex
|
||||
import coursier.cli.util.{JsonElem, JsonPrintRequirement, JsonReport}
|
||||
import coursier.extra.Typelevel
|
||||
import coursier.interop.scalaz._
|
||||
import coursier.ivy.IvyRepository
|
||||
import coursier.util.Parse.ModuleRequirements
|
||||
import coursier.util.{Parse, Print}
|
||||
import coursier.util.{Gather, Parse, Print}
|
||||
|
||||
import scala.annotation.tailrec
|
||||
import scala.concurrent.duration.Duration
|
||||
import scalaz.concurrent.{Strategy, Task}
|
||||
import scalaz.Nondeterminism
|
||||
|
||||
|
||||
object Helper {
|
||||
|
|
@ -145,14 +145,14 @@ class Helper(
|
|||
None
|
||||
|
||||
val fetchs = cachePolicies.map(p =>
|
||||
Cache.fetch(cache, p, checksums = Nil, logger = logger, pool = pool, ttl = ttl0)
|
||||
Cache.fetch[Task](cache, p, checksums = Nil, logger = logger, pool = pool, ttl = ttl0)
|
||||
)
|
||||
|
||||
logger.foreach(_.init())
|
||||
|
||||
val scaladex = Scaladex.cached(fetchs: _*)
|
||||
|
||||
val res = Nondeterminism[Task].gather(scaladexRawDependencies.map { s =>
|
||||
val res = Gather[Task].gather(scaladexRawDependencies.map { s =>
|
||||
val deps = scaladex.dependencies(
|
||||
s,
|
||||
scalaVersion,
|
||||
|
|
@ -192,6 +192,7 @@ class Helper(
|
|||
.collect { case Right(l) => l }
|
||||
.flatten
|
||||
.map { case (mod, ver) => (Dependency(mod, ver), Map[String, String]()) }
|
||||
.toList
|
||||
}
|
||||
|
||||
val (forceVersionErrors, forceVersions0) = Parse.moduleVersions(forceVersion, scalaVersion)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package coursier.cli
|
||||
|
||||
import java.io.{BufferedReader, File, InputStream, InputStreamReader, PipedInputStream, PipedOutputStream, PrintStream}
|
||||
import java.nio.charset.StandardCharsets.UTF_8
|
||||
|
||||
import coursier.internal.FileUtil
|
||||
|
||||
|
|
@ -55,7 +56,7 @@ object SparkOutputHelper {
|
|||
if (!written) {
|
||||
println(s"Detected YARN app ID $id")
|
||||
Option(yarnAppFile.getParentFile).foreach(_.mkdirs())
|
||||
FileUtil.write(yarnAppFile, id.getBytes("UTF-8"))
|
||||
FileUtil.write(yarnAppFile, id.getBytes(UTF_8))
|
||||
written = true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,11 +6,9 @@ import java.util.concurrent.ExecutorService
|
|||
|
||||
import argonaut._, Argonaut._, ArgonautShapeless._
|
||||
import coursier.core.{Artifact, Attributes}
|
||||
import coursier.util.EitherT
|
||||
import coursier.interop.scalaz._
|
||||
import coursier.util.{EitherT, Gather}
|
||||
import coursier.{Fetch, Module}
|
||||
|
||||
import scala.language.higherKinds
|
||||
import scalaz.Nondeterminism
|
||||
import scalaz.concurrent.Task
|
||||
|
||||
object Scaladex {
|
||||
|
|
@ -48,7 +46,7 @@ object Scaladex {
|
|||
|
||||
Right(new String(b, StandardCharsets.UTF_8))
|
||||
})(pool))
|
||||
}, Nondeterminism[Task])
|
||||
}, Gather[Task])
|
||||
|
||||
def cached(fetch: Fetch.Content[Task]*): Scaladex[Task] =
|
||||
Scaladex({
|
||||
|
|
@ -59,13 +57,13 @@ object Scaladex {
|
|||
)
|
||||
|
||||
(get(fetch.head) /: fetch.tail)(_ orElse get(_))
|
||||
}, Nondeterminism[Task])
|
||||
}, Gather[Task])
|
||||
}
|
||||
|
||||
// TODO Add F[_] type param, change `fetch` type to `String => EitherT[F, String, String]`, adjust method signatures accordingly, ...
|
||||
case class Scaladex[F[_]](fetch: String => EitherT[F, String, String], F: Nondeterminism[F]) {
|
||||
case class Scaladex[F[_]](fetch: String => EitherT[F, String, String], G: Gather[F]) {
|
||||
|
||||
private implicit def F0 = F
|
||||
private implicit val G0 = G
|
||||
|
||||
// quick & dirty API for querying scaladex
|
||||
|
||||
|
|
@ -141,8 +139,8 @@ case class Scaladex[F[_]](fetch: String => EitherT[F, String, String], F: Nondet
|
|||
orgNameOrError.flatMap {
|
||||
case (ghOrg, ghRepo, artifactNames) =>
|
||||
|
||||
val moduleVersions = F.map(F.gather(artifactNames.map { artifactName =>
|
||||
F.map(artifactInfos(ghOrg, ghRepo, artifactName).run) {
|
||||
val moduleVersions = G.map(G.gather(artifactNames.map { artifactName =>
|
||||
G.map(artifactInfos(ghOrg, ghRepo, artifactName).run) {
|
||||
case Left(err) =>
|
||||
logger(s"Cannot get infos about artifact $artifactName from $ghOrg/$ghRepo: $err, ignoring it")
|
||||
Nil
|
||||
|
|
@ -152,7 +150,7 @@ case class Scaladex[F[_]](fetch: String => EitherT[F, String, String], F: Nondet
|
|||
}
|
||||
}))(_.flatten)
|
||||
|
||||
EitherT(F.map(moduleVersions) { l =>
|
||||
EitherT(G.map(moduleVersions) { l =>
|
||||
if (l.isEmpty)
|
||||
Left(s"No module found for $ghOrg/$ghRepo")
|
||||
else
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ package coursier.cli.spark
|
|||
|
||||
import java.io.{File, FileInputStream, FileOutputStream}
|
||||
import java.math.BigInteger
|
||||
import java.nio.charset.StandardCharsets.UTF_8
|
||||
import java.nio.file.{Files, StandardCopyOption}
|
||||
import java.security.MessageDigest
|
||||
import java.util.jar.{Attributes, JarFile, JarOutputStream, Manifest}
|
||||
import java.util.regex.Pattern
|
||||
|
|
@ -207,7 +209,7 @@ object Assembly {
|
|||
extraDependencies: Seq[String],
|
||||
options: CommonOptions,
|
||||
artifactTypes: Set[String],
|
||||
checksumSeed: Array[Byte] = "v1".getBytes("UTF-8")
|
||||
checksumSeed: Array[Byte] = "v1".getBytes(UTF_8)
|
||||
): Either[String, (File, Seq[File])] = {
|
||||
|
||||
val helper = sparkJarsHelper(scalaVersion, sparkVersion, yarnVersion, default, extraDependencies, options)
|
||||
|
|
@ -240,7 +242,7 @@ object Assembly {
|
|||
md.update(checksumSeed)
|
||||
|
||||
for (c <- checksums.sorted) {
|
||||
val b = c.getBytes("UTF-8")
|
||||
val b = c.getBytes(UTF_8)
|
||||
md.update(b, 0, b.length)
|
||||
}
|
||||
|
||||
|
|
@ -271,7 +273,7 @@ object Assembly {
|
|||
val tmpDest = new File(dest.getParentFile, s".${dest.getName}.part")
|
||||
// FIXME Acquire lock on tmpDest
|
||||
Assembly.make(jars, tmpDest, assemblyRules)
|
||||
FileUtil.atomicMove(tmpDest, dest)
|
||||
Files.move(tmpDest.toPath, dest.toPath, StandardCopyOption.ATOMIC_MOVE)
|
||||
Right((dest, jars))
|
||||
}.left.map(_.describe)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ junit_tests(
|
|||
scala_library(
|
||||
name='lib',
|
||||
dependencies = [
|
||||
"cache/src/main/scala:cache"
|
||||
"cache:cache"
|
||||
],
|
||||
sources = ["CliTestLib.scala"],
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package coursier.cli
|
||||
|
||||
import java.io._
|
||||
import java.nio.charset.StandardCharsets.UTF_8
|
||||
import java.util.zip.ZipInputStream
|
||||
|
||||
import caseapp.core.RemainingArgs
|
||||
|
|
@ -69,7 +70,7 @@ class CliBootstrapIntegrationTest extends FlatSpec with CliTestLib {
|
|||
|
||||
val zis = new ZipInputStream(new ByteArrayInputStream(actualContent))
|
||||
|
||||
val lines = new String(zipEntryContent(zis, "bootstrap-isolation-foo-jar-urls"), "UTF-8").lines.toVector
|
||||
val lines = new String(zipEntryContent(zis, "bootstrap-isolation-foo-jar-urls"), UTF_8).lines.toVector
|
||||
|
||||
val extensions = lines
|
||||
.map { l =>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ scala_library(
|
|||
name = "core",
|
||||
dependencies = [
|
||||
"3rdparty/jvm:fastParse",
|
||||
"3rdparty/jvm:scalaz-core",
|
||||
"3rdparty/jvm:jsoup",
|
||||
# TODO(wisechengyi) for some reason there is no compile error
|
||||
# and this is needed at runtime.
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@ package coursier
|
|||
|
||||
import coursier.util.{EitherT, Gather, Monad}
|
||||
|
||||
import scala.language.higherKinds
|
||||
|
||||
object Fetch {
|
||||
|
||||
type Content[F[_]] = Artifact => EitherT[F, String, String]
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package coursier.core
|
|||
|
||||
import coursier.Fetch
|
||||
|
||||
import scala.language.higherKinds
|
||||
import coursier.core.compatibility.encodeURIComponent
|
||||
import coursier.util.{EitherT, Monad}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ package core
|
|||
import coursier.util.Monad
|
||||
|
||||
import scala.annotation.tailrec
|
||||
import scala.language.higherKinds
|
||||
|
||||
|
||||
sealed abstract class ResolutionProcess {
|
||||
|
|
|
|||
|
|
@ -4,8 +4,6 @@ import coursier.Fetch
|
|||
import coursier.core._
|
||||
import coursier.util.{EitherT, Monad, WebPage}
|
||||
|
||||
import scala.language.higherKinds
|
||||
|
||||
final case class IvyRepository(
|
||||
pattern: Pattern,
|
||||
metadataPatternOpt: Option[Pattern],
|
||||
|
|
|
|||
|
|
@ -4,8 +4,6 @@ import coursier.util.Traverse.TraverseOps
|
|||
import coursier.util.ValidationNel
|
||||
import fastparse.all._
|
||||
|
||||
import scala.language.implicitConversions
|
||||
|
||||
final case class PropertiesPattern(chunks: Seq[PropertiesPattern.ChunkOrProperty]) {
|
||||
|
||||
def string: String = chunks.map(_.string).mkString
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@ import coursier.core._
|
|||
import coursier.core.compatibility.encodeURIComponent
|
||||
import coursier.util.{EitherT, Monad, WebPage}
|
||||
|
||||
import scala.language.higherKinds
|
||||
|
||||
object MavenRepository {
|
||||
val SnapshotTimestamp = "(.*-)?[0-9]{8}\\.[0-9]{6}-[0-9]+".r
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
package coursier.util
|
||||
|
||||
import scala.language.higherKinds
|
||||
|
||||
final case class EitherT[F[_], L, R](run: F[Either[L, R]]) {
|
||||
|
||||
def map[S](f: R => S)(implicit M: Monad[F]): EitherT[F, L, S] =
|
||||
|
|
@ -44,11 +42,6 @@ final case class EitherT[F[_], L, R](run: F[Either[L, R]]) {
|
|||
}
|
||||
)
|
||||
|
||||
def scalaz(implicit M: Monad[F]): _root_.scalaz.EitherT[F, L, R] =
|
||||
_root_.scalaz.EitherT(
|
||||
M.map(run)(_root_.scalaz.\/.fromEither)
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
object EitherT {
|
||||
|
|
|
|||
|
|
@ -1,18 +1,9 @@
|
|||
package coursier.util
|
||||
|
||||
import scala.language.higherKinds
|
||||
|
||||
trait Gather[F[_]] extends Monad[F] {
|
||||
def gather[A](elems: Seq[F[A]]): F[Seq[A]]
|
||||
}
|
||||
|
||||
object Gather {
|
||||
|
||||
implicit def fromScalaz[F[_]](implicit N: scalaz.Nondeterminism[F]): Gather[F] =
|
||||
new Gather[F] {
|
||||
def point[A](a: A) = N.pure(a)
|
||||
def bind[A, B](elem: F[A])(f: A => F[B]) = N.bind(elem)(f)
|
||||
def gather[A](elems: Seq[F[A]]) = N.map(N.gather(elems))(l => l)
|
||||
}
|
||||
|
||||
def apply[F[_]](implicit G: Gather[F]): Gather[F] = G
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
package coursier.util
|
||||
|
||||
import scala.language.higherKinds
|
||||
|
||||
trait Monad[F[_]] {
|
||||
def point[A](a: A): F[A]
|
||||
def bind[A, B](elem: F[A])(f: A => F[B]): F[B]
|
||||
|
|
@ -9,13 +7,3 @@ trait Monad[F[_]] {
|
|||
def map[A, B](elem: F[A])(f: A => B): F[B] =
|
||||
bind(elem)(a => point(f(a)))
|
||||
}
|
||||
|
||||
object Monad {
|
||||
|
||||
implicit def fromScalaz[F[_]](implicit M: scalaz.Monad[F]): Monad[F] =
|
||||
new Monad[F] {
|
||||
def point[A](a: A) = M.pure(a)
|
||||
def bind[A, B](elem: F[A])(f: A => F[B]) = M.bind(elem)(f)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -166,8 +166,8 @@ object Cache {
|
|||
dropInfoAttributes = true
|
||||
)
|
||||
|
||||
def fetch() = coursier.Cache.fetch()
|
||||
def file(artifact: Artifact) = coursier.Cache.file(artifact)
|
||||
def fetch[F[_]: coursier.util.Schedulable]() = coursier.Cache.fetch[F]()
|
||||
def file[F[_]: coursier.util.Schedulable](artifact: Artifact) = coursier.Cache.file[F](artifact)
|
||||
}
|
||||
```
|
||||
|
||||
|
|
@ -187,17 +187,21 @@ val start = Resolution(
|
|||
|
||||
Create a fetch function able to get things from a few repositories via a local cache,
|
||||
```tut:silent
|
||||
import coursier.util.Task
|
||||
|
||||
val repositories = Seq(
|
||||
Cache.ivy2Local,
|
||||
MavenRepository("https://repo1.maven.org/maven2")
|
||||
)
|
||||
|
||||
val fetch = Fetch.from(repositories, Cache.fetch())
|
||||
val fetch = Fetch.from(repositories, Cache.fetch[Task]())
|
||||
```
|
||||
|
||||
Then run the resolution per-se,
|
||||
```tut:silent
|
||||
val resolution = start.process.run(fetch).unsafePerformSync
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
|
||||
val resolution = start.process.run(fetch).unsafeRun()
|
||||
```
|
||||
That will fetch and use metadata.
|
||||
|
||||
|
|
@ -210,11 +214,11 @@ These would mean that the resolution wasn't able to get metadata about some depe
|
|||
Then fetch and get local copies of the artifacts themselves (the JARs) with
|
||||
```tut:silent
|
||||
import java.io.File
|
||||
import scalaz.concurrent.Task
|
||||
import coursier.util.Gather
|
||||
|
||||
val localArtifacts: Seq[Either[FileError, File]] = Task.gatherUnordered(
|
||||
resolution.artifacts.map(Cache.file(_).run)
|
||||
).unsafePerformSync
|
||||
val localArtifacts: Seq[Either[FileError, File]] = Gather[Task].gather(
|
||||
resolution.artifacts.map(Cache.file[Task](_).run)
|
||||
).unsafeRun()
|
||||
```
|
||||
|
||||
|
||||
|
|
@ -544,7 +548,7 @@ Given a sequence of dependencies, designated by their `Module` (organisation and
|
|||
and version (just a `String`), it gives either errors (`Seq[String]`) or metadata (`(Artifact.Source, Project)`),
|
||||
wrapping the whole in a monad `F`.
|
||||
```tut:silent
|
||||
val fetch = Fetch.from(repositories, Cache.fetch())
|
||||
val fetch = Fetch.from(repositories, Cache.fetch[Task]())
|
||||
```
|
||||
|
||||
The monad used by `Fetch.from` is `scalaz.concurrent.Task`, but the resolution process is not tied to a particular
|
||||
|
|
@ -570,7 +574,9 @@ resolution is particularly complex, in which case `maxIterations` could be incre
|
|||
|
||||
Let's run the whole resolution,
|
||||
```tut:silent
|
||||
val resolution = start.process.run(fetch).unsafePerformSync
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
|
||||
val resolution = start.process.run(fetch).unsafeRun()
|
||||
```
|
||||
|
||||
To get additional feedback during the resolution, we can give the `Cache.default` method above
|
||||
|
|
@ -594,11 +600,11 @@ which are dependencies whose versions could not be unified.
|
|||
Then, if all went well, we can fetch and get local copies of the artifacts themselves (the JARs) with
|
||||
```tut:silent
|
||||
import java.io.File
|
||||
import scalaz.concurrent.Task
|
||||
import coursier.util.Gather
|
||||
|
||||
val localArtifacts: Seq[Either[FileError, File]] = Task.gatherUnordered(
|
||||
resolution.artifacts.map(Cache.file(_).run)
|
||||
).unsafePerformSync
|
||||
val localArtifacts: Seq[Either[FileError, File]] = Gather[Task].gather(
|
||||
resolution.artifacts.map(Cache.file[Task](_).run)
|
||||
).unsafeRun()
|
||||
```
|
||||
|
||||
We're using the `Cache.file` method, that can also be given a `Logger` (for more feedback) and a custom thread pool.
|
||||
|
|
|
|||
|
|
@ -32,7 +32,8 @@ object Native {
|
|||
Seq(s"$binaryName$major$minor", s"$binaryName-$major.$minor")
|
||||
} :+ binaryName
|
||||
|
||||
Process("which" +: binaryNames).lines_!
|
||||
Process("which" +: binaryNames)
|
||||
.lineStream_!
|
||||
.map(new File(_))
|
||||
.headOption
|
||||
.getOrElse {
|
||||
|
|
@ -325,7 +326,7 @@ object Native {
|
|||
val compileOpts = {
|
||||
val includes = {
|
||||
val includedir =
|
||||
Try(Process("llvm-config --includedir").lines_!)
|
||||
Try(Process("llvm-config --includedir").lineStream_!)
|
||||
.getOrElse(Seq.empty)
|
||||
("/usr/local/include" +: includedir).map(s => s"-I$s")
|
||||
}
|
||||
|
|
@ -392,7 +393,7 @@ object Native {
|
|||
val nativeCompileOptions = {
|
||||
val includes = {
|
||||
val includedir =
|
||||
Try(Process("llvm-config --includedir").lines_!)
|
||||
Try(Process("llvm-config --includedir").lineStream_!)
|
||||
.getOrElse(Seq.empty)
|
||||
("/usr/local/include" +: includedir).map(s => s"-I$s")
|
||||
}
|
||||
|
|
@ -444,7 +445,7 @@ object Native {
|
|||
val nativeLinkingOptions = {
|
||||
val libs = {
|
||||
val libdir =
|
||||
Try(Process("llvm-config --libdir").lines_!)
|
||||
Try(Process("llvm-config --libdir").lineStream_!)
|
||||
.getOrElse(Seq.empty)
|
||||
("/usr/local/lib" +: libdir).map(s => s"-L$s")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ scala_library(
|
|||
name = "fallback-deps-repo",
|
||||
dependencies = [
|
||||
"core:core",
|
||||
"cache/src/main/scala:cache",
|
||||
"cache:cache",
|
||||
],
|
||||
sources = globs("*.scala"),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@ import java.net.{HttpURLConnection, URL, URLConnection}
|
|||
|
||||
import coursier.util.{EitherT, Monad}
|
||||
|
||||
import scala.language.higherKinds
|
||||
|
||||
object FallbackDependenciesRepository {
|
||||
|
||||
def exists(url: URL): Boolean = {
|
||||
|
|
|
|||
|
|
@ -1,52 +0,0 @@
|
|||
package coursier
|
||||
|
||||
import scala.concurrent.{ ExecutionContext, Future }
|
||||
import scalaz.{ Nondeterminism, Reducer }
|
||||
|
||||
/**
|
||||
* Minimal Future-based Task.
|
||||
*
|
||||
* Likely to be flawed and/or sub-optimal, but does the job.
|
||||
*/
|
||||
trait Task[T] { self =>
|
||||
def map[U](f: T => U): Task[U] =
|
||||
new Task[U] {
|
||||
def runF(implicit ec: ExecutionContext) = self.runF.map(f)
|
||||
}
|
||||
def flatMap[U](f: T => Task[U]): Task[U] =
|
||||
new Task[U] {
|
||||
def runF(implicit ec: ExecutionContext) = self.runF.flatMap(f(_).runF)
|
||||
}
|
||||
|
||||
def runF(implicit ec: ExecutionContext): Future[T]
|
||||
}
|
||||
|
||||
object Task {
|
||||
def now[A](a: A): Task[A] =
|
||||
new Task[A] {
|
||||
def runF(implicit ec: ExecutionContext) = Future.successful(a)
|
||||
}
|
||||
def apply[A](f: ExecutionContext => Future[A]): Task[A] =
|
||||
new Task[A] {
|
||||
def runF(implicit ec: ExecutionContext) = f(ec)
|
||||
}
|
||||
def gatherUnordered[T](tasks: Seq[Task[T]], exceptionCancels: Boolean = false): Task[Seq[T]] =
|
||||
new Task[Seq[T]] {
|
||||
def runF(implicit ec: ExecutionContext) = Future.traverse(tasks)(_.runF)
|
||||
}
|
||||
|
||||
implicit val taskMonad: Nondeterminism[Task] =
|
||||
new Nondeterminism[Task] {
|
||||
def point[A](a: => A): Task[A] = Task.now(a)
|
||||
def bind[A,B](fa: Task[A])(f: A => Task[B]): Task[B] = fa.flatMap(f)
|
||||
override def reduceUnordered[A, M](fs: Seq[Task[A]])(implicit R: Reducer[A, M]): Task[M] =
|
||||
Task { implicit ec =>
|
||||
val f = Future.sequence(fs.map(_.runF))
|
||||
f.map { l =>
|
||||
(R.zero /: l)(R.snoc)
|
||||
}
|
||||
}
|
||||
def chooseAny[A](head: Task[A], tail: Seq[Task[A]]): Task[(A, Seq[Task[A]])] =
|
||||
???
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,6 @@
|
|||
|
||||
import java.nio.file.Files
|
||||
|
||||
import sbt._
|
||||
import sbt.Keys._
|
||||
import sbt.ScriptedPlugin.autoImport.{sbtLauncher, scriptedBufferLog, ScriptedLaunchConf, scriptedLaunchOpts}
|
||||
|
|
@ -31,30 +33,42 @@ object Settings {
|
|||
scalazBintrayRepository,
|
||||
sonatypeRepository("releases"),
|
||||
crossScalaVersions := Seq(scala212, scala211, scala210), // defined for all projects to trump sbt-doge
|
||||
scalacOptions ++= {
|
||||
val targetJvm = scalaBinaryVersion.value match {
|
||||
case "2.10" | "2.11" =>
|
||||
Seq("-target:jvm-1.6")
|
||||
case _ =>
|
||||
Seq()
|
||||
}
|
||||
|
||||
targetJvm ++ Seq("-feature", "-deprecation")
|
||||
},
|
||||
javacOptions ++= {
|
||||
scalaBinaryVersion.value match {
|
||||
case "2.10" | "2.11" =>
|
||||
Seq(
|
||||
"-source", "1.6",
|
||||
"-target", "1.6"
|
||||
)
|
||||
case _ =>
|
||||
Seq()
|
||||
}
|
||||
},
|
||||
scalacOptions ++= Seq(
|
||||
"-target:jvm-1.8",
|
||||
"-feature",
|
||||
"-deprecation",
|
||||
"-language:higherKinds",
|
||||
"-language:implicitConversions"
|
||||
),
|
||||
javacOptions ++= Seq(
|
||||
"-source", "1.8",
|
||||
"-target", "1.8"
|
||||
),
|
||||
javacOptions.in(Keys.doc) := Seq()
|
||||
)
|
||||
|
||||
val runNpmInstallIfNeeded = Def.task {
|
||||
val baseDir = baseDirectory.in(ThisBuild).value
|
||||
val evFile = baseDir / "node_modules" / ".npm_run"
|
||||
val log = streams.value.log
|
||||
if (!evFile.exists()) {
|
||||
val cmd = Seq("npm", "install")
|
||||
val b = new ProcessBuilder(cmd: _*)
|
||||
b.directory(baseDir)
|
||||
b.inheritIO()
|
||||
log.info(s"Running ${cmd.mkString(" ")}")
|
||||
val p = b.start()
|
||||
val retCode = p.waitFor()
|
||||
if (retCode == 0)
|
||||
log.info(s"${cmd.mkString(" ")} ran successfully")
|
||||
else
|
||||
sys.error(s"${cmd.mkString(" ")} failed (return code $retCode)")
|
||||
|
||||
// Parent dir should have been created by npm install
|
||||
Files.write(evFile.toPath, Array.emptyByteArray)
|
||||
}
|
||||
}
|
||||
|
||||
lazy val shared = javaScalaPluginShared ++ Seq(
|
||||
scalaVersion := scala212,
|
||||
libs ++= {
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ object CoursierPlugin extends AutoPlugin {
|
|||
IvyXml.writeFiles(currentProject, shadedConfigOpt, ivySbt.value, streams.value.log)
|
||||
}).value
|
||||
|
||||
private val pluginIvySnapshotsBase = Resolver.SbtPluginRepositoryRoot.stripSuffix("/") + "/ivy-snapshots"
|
||||
private val pluginIvySnapshotsBase = Resolver.SbtRepositoryRoot.stripSuffix("/") + "/ivy-snapshots"
|
||||
|
||||
// allows to get the actual repo list when sbt starts up
|
||||
private val hackHack = Seq(
|
||||
|
|
@ -93,25 +93,33 @@ object CoursierPlugin extends AutoPlugin {
|
|||
|
||||
// hack to trigger https://github.com/sbt/sbt/blob/v1.0.1/main/src/main/scala/sbt/Defaults.scala#L2856,
|
||||
// to have the third case be used instead of the second one, at https://github.com/sbt/sbt/blob/v1.0.1/main/src/main/scala/sbt/Defaults.scala#L2069
|
||||
// 😃🔫
|
||||
new xsbti.AppConfiguration {
|
||||
def provider() = {
|
||||
import scala.language.reflectiveCalls
|
||||
val prov = app.provider()
|
||||
val noWarningForDeprecatedStuffProv = prov.asInstanceOf[{
|
||||
def mainClass(): Class[_ <: xsbti.AppMain]
|
||||
}]
|
||||
new xsbti.AppProvider {
|
||||
def newMain() = prov.newMain()
|
||||
def components() = prov.components()
|
||||
def mainClass() = prov.mainClass()
|
||||
def mainClass() = noWarningForDeprecatedStuffProv.mainClass()
|
||||
def mainClasspath() = prov.mainClasspath()
|
||||
def loader() = prov.loader()
|
||||
def scalaProvider() = {
|
||||
val scalaProv = prov.scalaProvider()
|
||||
val noWarningForDeprecatedStuffScalaProv = scalaProv.asInstanceOf[{
|
||||
def libraryJar(): File
|
||||
def compilerJar(): File
|
||||
}]
|
||||
|
||||
new xsbti.ScalaProvider {
|
||||
def app(id: xsbti.ApplicationID) = scalaProv.app(id)
|
||||
def loader() = scalaProv.loader()
|
||||
def jars() = scalaProv.jars()
|
||||
def libraryJar() = scalaProv.libraryJar()
|
||||
def libraryJar() = noWarningForDeprecatedStuffScalaProv.libraryJar()
|
||||
def version() = scalaProv.version()
|
||||
def compilerJar() = scalaProv.compilerJar()
|
||||
def compilerJar() = noWarningForDeprecatedStuffScalaProv.compilerJar()
|
||||
def launcher() = {
|
||||
val launch = scalaProv.launcher()
|
||||
new xsbti.Launcher {
|
||||
|
|
@ -142,17 +150,12 @@ object CoursierPlugin extends AutoPlugin {
|
|||
}
|
||||
)
|
||||
|
||||
private val preloadedBase = {
|
||||
val rawPattern = "file:///${sbt.preloaded-${sbt.global.base-${user.home}/.sbt}/preloaded/}"
|
||||
Tasks.exceptionPatternParser().apply(rawPattern).string
|
||||
}
|
||||
|
||||
def coursierSettings(
|
||||
shadedConfigOpt: Option[(String, String)],
|
||||
packageConfigs: Seq[(Configuration, String)]
|
||||
) = hackHack ++ Seq(
|
||||
clean := {
|
||||
clean.value
|
||||
val noWarningPlz = clean.value
|
||||
Tasks.resolutionsCache.clear()
|
||||
Tasks.reportsCache.clear()
|
||||
},
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@ package coursier
|
|||
|
||||
import coursier.util.{EitherT, Monad}
|
||||
|
||||
import scala.language.higherKinds
|
||||
|
||||
final case class InterProjectRepository(projects: Seq[Project]) extends Repository {
|
||||
|
||||
private val map = projects
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package coursier
|
||||
|
||||
import java.nio.charset.StandardCharsets.UTF_8
|
||||
|
||||
import coursier.internal.FileUtil
|
||||
import org.apache.ivy.core.module.id.ModuleRevisionId
|
||||
|
||||
|
|
@ -52,7 +54,7 @@ object IvyXml {
|
|||
val content0 = rawContent(currentProject, shadedConfigOpt)
|
||||
cacheIvyFile.getParentFile.mkdirs()
|
||||
log.info(s"Writing Ivy file $cacheIvyFile")
|
||||
FileUtil.write(cacheIvyFile, content0.getBytes("UTF-8"))
|
||||
FileUtil.write(cacheIvyFile, content0.getBytes(UTF_8))
|
||||
|
||||
// Just writing an empty file here... Are these only used?
|
||||
cacheIvyPropertiesFile.getParentFile.mkdirs()
|
||||
|
|
|
|||
|
|
@ -4,9 +4,7 @@ final class ResolutionException(
|
|||
val error: ResolutionError
|
||||
) extends Exception(
|
||||
error.message,
|
||||
error.cause.orNull
|
||||
) {
|
||||
// not using the 4-arg Exception constructor, only available with Java >= 7
|
||||
|
||||
setStackTrace(Array()) // don't keep stack trace around (improves readability from the SBT console)
|
||||
}
|
||||
error.cause.orNull,
|
||||
true,
|
||||
false // don't keep stack trace around (improves readability from the SBT console)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@ package coursier
|
|||
|
||||
import sbt._
|
||||
|
||||
import scala.language.implicitConversions
|
||||
|
||||
// things from sbt-structure
|
||||
object Structure {
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import java.util.concurrent.{ConcurrentHashMap, ExecutorService, Executors}
|
|||
|
||||
import coursier.core.{Authentication, Publication}
|
||||
import coursier.extra.Typelevel
|
||||
import coursier.interop.scalaz._
|
||||
import coursier.ivy.{IvyRepository, PropertiesPattern}
|
||||
import coursier.Keys._
|
||||
import coursier.Structure._
|
||||
|
|
@ -1015,7 +1016,7 @@ object Tasks {
|
|||
|
||||
val artifactFileOrErrorTasks = allArtifacts.toVector.distinct.map { a =>
|
||||
def f(p: CachePolicy) =
|
||||
Cache.file(
|
||||
Cache.file[Task](
|
||||
a,
|
||||
cache,
|
||||
p,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import utest._
|
|||
|
||||
object IvyXmlTests extends TestSuite {
|
||||
|
||||
val tests = TestSuite {
|
||||
val tests = Tests {
|
||||
"no truncation" - {
|
||||
|
||||
val project = Project(
|
||||
|
|
|
|||
|
|
@ -3,4 +3,8 @@ package coursier
|
|||
object SbtCompatibility {
|
||||
def needsIvyXmlLocal = List(sbt.Keys.deliverLocalConfiguration)
|
||||
def needsIvyXml = List(sbt.Keys.deliverConfiguration)
|
||||
|
||||
implicit class ResolverCompationExtraOps(val res: sbt.Resolver.type) {
|
||||
def SbtRepositoryRoot = res.SbtPluginRepositoryRoot
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
scala_library(
|
||||
name = "scalaz-interop",
|
||||
dependencies = [
|
||||
"core:core",
|
||||
"cache:cache",
|
||||
"3rdparty/jvm:scalaz-concurrent",
|
||||
],
|
||||
sources = rglobs("jvm/*.scala", "shared/*.scala"),
|
||||
)
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
package coursier.interop
|
||||
|
||||
abstract class PlatformScalazImplicits
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package coursier.interop
|
||||
|
||||
import java.util.concurrent.ExecutorService
|
||||
|
||||
import coursier.util.Schedulable
|
||||
import _root_.scalaz.concurrent.{Task => ScalazTask}
|
||||
|
||||
abstract class PlatformScalazImplicits {
|
||||
|
||||
implicit val scalazTaskSchedulable: Schedulable[ScalazTask] =
|
||||
new Schedulable[ScalazTask] {
|
||||
def point[A](a: A) =
|
||||
ScalazTask.point(a)
|
||||
def schedule[A](pool: ExecutorService)(f: => A) =
|
||||
ScalazTask(f)(pool)
|
||||
|
||||
def gather[A](elems: Seq[ScalazTask[A]]) =
|
||||
ScalazTask.taskInstance.gather(elems)
|
||||
|
||||
def bind[A, B](elem: ScalazTask[A])(f: A => ScalazTask[B]) =
|
||||
ScalazTask.taskInstance.bind(elem)(f)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package coursier.interop
|
||||
|
||||
import coursier.util.{Gather, Monad}
|
||||
|
||||
object scalaz extends LowPriorityScalazImplicits {
|
||||
|
||||
implicit def coursierMonadFromScalaz[F[_]](implicit M: _root_.scalaz.Monad[F]): Monad[F] =
|
||||
new Monad[F] {
|
||||
def point[A](a: A) = M.pure(a)
|
||||
def bind[A, B](elem: F[A])(f: A => F[B]) = M.bind(elem)(f)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
abstract class LowPriorityScalazImplicits extends PlatformScalazImplicits {
|
||||
|
||||
implicit def coursierGatherFromScalaz[F[_]](implicit N: _root_.scalaz.Nondeterminism[F]): Gather[F] =
|
||||
new Gather[F] {
|
||||
def point[A](a: A) = N.pure(a)
|
||||
def bind[A, B](elem: F[A])(f: A => F[B]) = N.bind(elem)(f)
|
||||
def gather[A](elems: Seq[F[A]]) = N.map(N.gather(elems))(l => l)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -70,7 +70,6 @@ sbtShading() {
|
|||
|
||||
runSbtCoursierTests() {
|
||||
addPgpKeys
|
||||
sbt ++$SCALA_VERSION sbt-plugins/publishLocal
|
||||
if [ "$SCALA_VERSION" = "2.10" ]; then
|
||||
sbt ++$SCALA_VERSION "sbt-coursier/scripted sbt-coursier/*" "sbt-coursier/scripted sbt-coursier-0.13/*"
|
||||
else
|
||||
|
|
@ -80,14 +79,14 @@ runSbtCoursierTests() {
|
|||
}
|
||||
|
||||
runSbtShadingTests() {
|
||||
sbt ++$SCALA_VERSION coreJVM/publishLocal cache/publishLocal extra/publishLocal sbt-shared/publishLocal sbt-coursier/publishLocal "sbt-shading/scripted sbt-shading/*"
|
||||
sbt ++$SCALA_VERSION "sbt-shading/scripted sbt-shading/*"
|
||||
if [ "$SCALA_VERSION" = "2.10" ]; then
|
||||
sbt ++$SCALA_VERSION "sbt-shading/scripted sbt-shading-0.13/*"
|
||||
fi
|
||||
}
|
||||
|
||||
jsCompile() {
|
||||
sbt ++$SCALA_VERSION js/compile js/test:compile coreJS/fastOptJS fetch-js/fastOptJS testsJS/test:fastOptJS js/test:fastOptJS
|
||||
sbt ++$SCALA_VERSION js/compile js/test:compile coreJS/fastOptJS cacheJS/fastOptJS testsJS/test:fastOptJS js/test:fastOptJS
|
||||
}
|
||||
|
||||
jvmCompile() {
|
||||
|
|
@ -131,53 +130,7 @@ validateReadme() {
|
|||
}
|
||||
|
||||
checkBinaryCompatibility() {
|
||||
sbt ++${SCALA_VERSION} coreJVM/mimaReportBinaryIssues cache/mimaReportBinaryIssues
|
||||
}
|
||||
|
||||
testSbtCoursierJava6() {
|
||||
sbt ++${SCALA_VERSION} coreJVM/publishLocal cache/publishLocal extra/publishLocal sbt-coursier/publishLocal
|
||||
|
||||
git clone https://github.com/alexarchambault/scalacheck-shapeless.git
|
||||
cd scalacheck-shapeless
|
||||
git checkout e11ec8b2b069ee598b20ae3f3ad6e00f5edfd7ac
|
||||
cd project
|
||||
clean_plugin_sbt
|
||||
cd project
|
||||
clean_plugin_sbt
|
||||
cd ../..
|
||||
docker run -it --rm \
|
||||
-v $HOME/.ivy2/local:/root/.ivy2/local \
|
||||
-v $(pwd):/root/project \
|
||||
-v $(pwd)/../bin:/root/bin \
|
||||
-e CI=true \
|
||||
openjdk:6-jre \
|
||||
/bin/bash -c "cd /root/project && /root/bin/sbt update"
|
||||
cd ..
|
||||
|
||||
# ensuring resolution error doesn't throw NoSuchMethodError
|
||||
mkdir -p foo/project
|
||||
cd foo
|
||||
echo 'libraryDependencies += "foo" % "bar" % "1.0"' >> build.sbt
|
||||
echo 'addSbtPlugin("io.get-coursier" % "sbt-coursier" % "'"$VERSION"'")' >> project/plugins.sbt
|
||||
echo 'sbt.version=0.13.15' >> project/build.properties
|
||||
docker run -it --rm \
|
||||
-v $HOME/.ivy2/local:/root/.ivy2/local \
|
||||
-v $(pwd):/root/project \
|
||||
-v $(pwd)/../bin:/root/bin \
|
||||
-e CI=true \
|
||||
openjdk:6-jre \
|
||||
/bin/bash -c "cd /root/project && /root/bin/sbt update || true" | tee -a output
|
||||
grep "coursier.ResolutionException: Encountered 1 error" output
|
||||
echo "Ok, found ResolutionException in output"
|
||||
cd ..
|
||||
}
|
||||
|
||||
clean_plugin_sbt() {
|
||||
mv plugins.sbt plugins.sbt0
|
||||
grep -v coursier plugins.sbt0 > plugins.sbt || true
|
||||
echo '
|
||||
addSbtPlugin("io.get-coursier" % "sbt-coursier" % "'"$VERSION"'")
|
||||
' >> plugins.sbt
|
||||
sbt ++${SCALA_VERSION} coreJVM/mimaReportBinaryIssues cacheJVM/mimaReportBinaryIssues
|
||||
}
|
||||
|
||||
publish() {
|
||||
|
|
@ -231,10 +184,6 @@ else
|
|||
if is210 || is212; then
|
||||
runSbtCoursierTests
|
||||
fi
|
||||
|
||||
if is210; then
|
||||
testSbtCoursierJava6
|
||||
fi
|
||||
elif sbtShading; then
|
||||
if is210 || is212; then
|
||||
runSbtShadingTests
|
||||
|
|
@ -250,10 +199,6 @@ else
|
|||
validateReadme
|
||||
checkBinaryCompatibility
|
||||
fi
|
||||
|
||||
# Not using a jdk6 matrix entry with Travis as some sources of coursier require Java 7 to compile
|
||||
# (even though it won't try to call Java 7 specific methods if it detects it runs under Java 6).
|
||||
# The tests here check that coursier is nonetheless fine when run under Java 6.
|
||||
fi
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import scala.concurrent.{ Future, Promise }
|
|||
|
||||
object JsTests extends TestSuite {
|
||||
|
||||
val tests = TestSuite {
|
||||
val tests = Tests {
|
||||
'promise{
|
||||
val p = Promise[Unit]()
|
||||
Future(p.success(()))
|
||||
|
|
@ -31,10 +31,10 @@ object JsTests extends TestSuite {
|
|||
assert(proj.parent == Some(Module("ch.qos.logback", "logback-parent"), "1.1.3"))
|
||||
}
|
||||
.run
|
||||
.runF
|
||||
.map{ res =>
|
||||
.map { res =>
|
||||
assert(res.isRight)
|
||||
}
|
||||
.future()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package coursier.test
|
||||
|
||||
import coursier.util.{EitherT, TestEscape}
|
||||
import coursier.{Fetch, Task}
|
||||
import coursier.util.{EitherT, Task, TestEscape}
|
||||
import coursier.Fetch
|
||||
|
||||
import scala.concurrent.{ExecutionContext, Future, Promise}
|
||||
import scala.scalajs.js
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ object DirectoryListingTests extends TestSuite {
|
|||
val module = Module("com.abc", "test")
|
||||
val version = "0.1"
|
||||
|
||||
val tests = TestSuite {
|
||||
val tests = Tests {
|
||||
'withListing - {
|
||||
'jar - CentralTests.withArtifacts(
|
||||
module,
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import coursier.maven.MavenRepository
|
|||
|
||||
object HttpAuthenticationTests extends TestSuite {
|
||||
|
||||
val tests = TestSuite {
|
||||
val tests = Tests {
|
||||
'httpAuthentication - {
|
||||
// requires an authenticated HTTP server to be running on localhost:8080 with user 'user'
|
||||
// and password 'pass'
|
||||
|
|
|
|||
|
|
@ -1,13 +1,11 @@
|
|||
package coursier
|
||||
|
||||
import java.io._
|
||||
import java.nio.charset.Charset
|
||||
import java.nio.charset.StandardCharsets.UTF_8
|
||||
|
||||
import coursier.util.EitherT
|
||||
import coursier.util.{EitherT, Task}
|
||||
|
||||
import scala.language.implicitConversions
|
||||
import scala.util.{Failure, Success, Try}
|
||||
import scalaz.concurrent.Task
|
||||
|
||||
object Platform {
|
||||
|
||||
|
|
@ -25,10 +23,8 @@ object Platform {
|
|||
buffer.toByteArray
|
||||
}
|
||||
|
||||
private lazy val UTF_8 = Charset.forName("UTF-8")
|
||||
|
||||
def readFully(is: => InputStream): Task[Either[String, String]] =
|
||||
Task {
|
||||
Task.delay {
|
||||
val t = Try {
|
||||
val is0 = is
|
||||
val b =
|
||||
|
|
|
|||
|
|
@ -2,19 +2,21 @@ package coursier
|
|||
package test
|
||||
|
||||
import java.io.File
|
||||
import java.nio.file.Files
|
||||
|
||||
import coursier.cache.protocol.TestprotocolHandler
|
||||
import coursier.internal.FileUtil
|
||||
|
||||
import coursier.util.Task
|
||||
import utest._
|
||||
|
||||
import scala.concurrent.{Await, ExecutionContext}
|
||||
import scala.concurrent.duration.Duration
|
||||
import scala.util.Try
|
||||
|
||||
object CacheFetchTests extends TestSuite {
|
||||
|
||||
def check(extraRepo: Repository): Unit = {
|
||||
|
||||
val tmpDir = FileUtil.createTempDirectory("coursier-cache-fetch-tests")
|
||||
val tmpDir = Files.createTempDirectory("coursier-cache-fetch-tests").toFile
|
||||
|
||||
def cleanTmpDir() = {
|
||||
def delete(f: File): Boolean =
|
||||
|
|
@ -30,36 +32,41 @@ object CacheFetchTests extends TestSuite {
|
|||
Console.err.println(s"Warning: unable to remove temporary directory $tmpDir")
|
||||
}
|
||||
|
||||
val res = try {
|
||||
val fetch = Fetch.from(
|
||||
Seq(
|
||||
extraRepo,
|
||||
MavenRepository("https://repo1.maven.org/maven2")
|
||||
),
|
||||
Cache.fetch(
|
||||
tmpDir
|
||||
val fetch = Fetch.from(
|
||||
Seq(
|
||||
extraRepo,
|
||||
MavenRepository("https://repo1.maven.org/maven2")
|
||||
),
|
||||
Cache.fetch[Task](
|
||||
tmpDir
|
||||
)
|
||||
)
|
||||
|
||||
val startRes = Resolution(
|
||||
Set(
|
||||
Dependency(
|
||||
Module("com.github.alexarchambault", "coursier_2.11"), "1.0.0-M9-test"
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
val startRes = Resolution(
|
||||
Set(
|
||||
Dependency(
|
||||
Module("com.github.alexarchambault", "coursier_2.11"), "1.0.0-M9-test"
|
||||
)
|
||||
)
|
||||
)
|
||||
val f = startRes
|
||||
.process
|
||||
.run(fetch)
|
||||
.future()(ExecutionContext.global)
|
||||
|
||||
startRes.process.run(fetch).unsafePerformSync
|
||||
} finally {
|
||||
cleanTmpDir()
|
||||
}
|
||||
val res =
|
||||
try Await.result(f, Duration.Inf)
|
||||
finally {
|
||||
cleanTmpDir()
|
||||
}
|
||||
|
||||
val errors = res.errors
|
||||
|
||||
assert(errors.isEmpty)
|
||||
}
|
||||
|
||||
val tests = TestSuite {
|
||||
val tests = Tests {
|
||||
|
||||
// using scala-test would allow to put the below comments in the test names...
|
||||
|
||||
|
|
|
|||
|
|
@ -4,13 +4,14 @@ package test
|
|||
import java.io.File
|
||||
import java.math.BigInteger
|
||||
|
||||
import coursier.util.{Gather, Schedulable, Task}
|
||||
import utest._
|
||||
|
||||
import scalaz.concurrent.Strategy
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
|
||||
|
||||
object ChecksumTests extends TestSuite {
|
||||
val tests = TestSuite {
|
||||
val tests = Tests {
|
||||
|
||||
'parse - {
|
||||
|
||||
|
|
@ -82,13 +83,13 @@ object ChecksumTests extends TestSuite {
|
|||
|
||||
val cache = new File(cachePath)
|
||||
|
||||
def validate(artifact: Artifact, sumType: String) =
|
||||
Cache.validateChecksum(
|
||||
def validate(artifact: Artifact, sumType: String): Task[Either[FileError, Unit]] =
|
||||
Cache.validateChecksum[Task](
|
||||
artifact,
|
||||
sumType,
|
||||
cache,
|
||||
Strategy.DefaultExecutorService
|
||||
).run.unsafePerformSync
|
||||
Schedulable.defaultThreadPool
|
||||
).run
|
||||
|
||||
def artifact(url: String) = Artifact(
|
||||
url,
|
||||
|
|
@ -109,11 +110,14 @@ object ChecksumTests extends TestSuite {
|
|||
"http://abc.com/com/github/alexarchambault/coursier_2.11/1.0.0-M9/coursier_2.11-1.0.0-M9.pom"
|
||||
).map(artifact)
|
||||
|
||||
def validateAll(sumType: String) =
|
||||
for (artifact <- artifacts) {
|
||||
val res = validate(artifact, sumType)
|
||||
assert(res.isRight)
|
||||
}
|
||||
def validateAll(sumType: String): Future[Seq[Unit]] =
|
||||
Gather[Task].gather(
|
||||
artifacts.map { artifact =>
|
||||
validate(artifact, sumType).map { res =>
|
||||
assert(res.isRight)
|
||||
}
|
||||
}
|
||||
).future()(ExecutionContext.global)
|
||||
|
||||
'sha1 - validateAll("SHA-1")
|
||||
'sha256 - validateAll("SHA-256")
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ object IvyTests extends TestSuite {
|
|||
throw new Exception("Cannot happen")
|
||||
)
|
||||
|
||||
val tests = TestSuite {
|
||||
val tests = Tests {
|
||||
'dropInfoAttributes - {
|
||||
CentralTests.resolutionCheck(
|
||||
module = Module(
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ object MavenTests extends TestSuite {
|
|||
|
||||
// only tested on the JVM for lack of support of XML attributes in the platform-dependent XML stubs
|
||||
|
||||
val tests = TestSuite {
|
||||
val tests = Tests {
|
||||
'testSnapshotNoVersioning - {
|
||||
|
||||
val dep = Dependency(
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import utest._
|
|||
|
||||
object PropertiesTests extends TestSuite {
|
||||
|
||||
val tests = TestSuite {
|
||||
val tests = Tests {
|
||||
|
||||
'version - {
|
||||
assert(Properties.version.nonEmpty)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import java.util.concurrent.ConcurrentHashMap
|
|||
|
||||
import coursier.{Fetch, Module}
|
||||
import coursier.core.ResolutionProcess
|
||||
import coursier.interop.scalaz._
|
||||
import utest._
|
||||
|
||||
import scala.collection.JavaConverters._
|
||||
|
|
@ -12,7 +13,7 @@ import scalaz.concurrent.Task
|
|||
|
||||
object ResolutionProcessTests extends TestSuite {
|
||||
|
||||
val tests = TestSuite {
|
||||
val tests = Tests {
|
||||
|
||||
'fetchAll - {
|
||||
|
||||
|
|
|
|||
|
|
@ -1,29 +1,24 @@
|
|||
package coursier.test
|
||||
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.nio.charset.StandardCharsets.UTF_8
|
||||
import java.nio.file.{Files, Paths}
|
||||
|
||||
import coursier.util.{EitherT, TestEscape}
|
||||
import coursier.util.{EitherT, Task, TestEscape}
|
||||
import coursier.{Cache, Fetch, Platform}
|
||||
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
import scalaz.concurrent.Task
|
||||
|
||||
package object compatibility {
|
||||
|
||||
implicit val executionContext = scala.concurrent.ExecutionContext.global
|
||||
|
||||
implicit class TaskExtensions[T](val underlying: Task[T]) extends AnyVal {
|
||||
def runF: Future[T] = Future.successful(underlying.unsafePerformSync)
|
||||
}
|
||||
|
||||
def textResource(path: String)(implicit ec: ExecutionContext): Future[String] = Future {
|
||||
val res = Option(getClass.getClassLoader.getResource(path)).getOrElse {
|
||||
throw new Exception(s"Not found: resource $path")
|
||||
}
|
||||
val is = res.openStream()
|
||||
|
||||
new String(Platform.readFullySync(is), "UTF-8")
|
||||
new String(Platform.readFullySync(is), UTF_8)
|
||||
}
|
||||
|
||||
private val baseRepo = {
|
||||
|
|
@ -48,9 +43,9 @@ package object compatibility {
|
|||
|
||||
val init = EitherT[Task, String, Unit] {
|
||||
if (Files.exists(path))
|
||||
Task.now(Right(()))
|
||||
Task.point(Right(()))
|
||||
else if (fillChunks)
|
||||
Task[Either[String, Unit]] {
|
||||
Task.delay[Either[String, Unit]] {
|
||||
Files.createDirectories(path.getParent)
|
||||
def is() = Cache.urlConnection(artifact.url, artifact.authentication).getInputStream
|
||||
val b = Platform.readFullySync(is())
|
||||
|
|
@ -61,7 +56,7 @@ package object compatibility {
|
|||
Left(e.toString)
|
||||
}
|
||||
else
|
||||
Task.now(Left(s"not found: $path"))
|
||||
Task.point(Left(s"not found: $path"))
|
||||
}
|
||||
|
||||
init.flatMap { _ =>
|
||||
|
|
@ -80,7 +75,7 @@ package object compatibility {
|
|||
if (fillChunks) {
|
||||
val path0 = baseResources.resolve(path)
|
||||
Files.createDirectories(path0.getParent)
|
||||
Files.write(path0, content.getBytes(StandardCharsets.UTF_8))
|
||||
Files.write(path0, content.getBytes(UTF_8))
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
io.get-coursier:coursier_2.11:1.1.0-SNAPSHOT:compile
|
||||
org.scala-lang:scala-library:2.11.12:default
|
||||
org.scala-lang.modules:scala-xml_2.11:1.0.6:default
|
||||
org.scalaz:scalaz-core_2.11:7.2.16:default
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ object ActivationTests extends TestSuite {
|
|||
// - condition on OS or JDK, but no OS or JDK info provided (-> no match)
|
||||
// - negated OS infos (starting with "!") - not implemented yet
|
||||
|
||||
val tests = TestSuite {
|
||||
val tests = Tests {
|
||||
'OS - {
|
||||
'fromProperties - {
|
||||
'MacOSX - {
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ abstract class CentralTests extends TestSuite {
|
|||
|
||||
res
|
||||
}
|
||||
.runF
|
||||
.future
|
||||
}
|
||||
|
||||
def resolutionCheck(
|
||||
|
|
@ -214,7 +214,7 @@ abstract class CentralTests extends TestSuite {
|
|||
assert(artifact.url.endsWith("." + extension))
|
||||
}
|
||||
|
||||
val tests = TestSuite {
|
||||
val tests = Tests {
|
||||
|
||||
'logback - {
|
||||
async {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ object ExclusionsTests extends TestSuite {
|
|||
def exclusionsAdd(e1: Set[(String, String)], e2: Set[(String, String)]) =
|
||||
core.Exclusions.minimize(e1 ++ e2)
|
||||
|
||||
val tests = TestSuite {
|
||||
val tests = Tests {
|
||||
val e1 = Set(("org1", "name1"))
|
||||
val e2 = Set(("org2", "name2"))
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import utest._
|
|||
|
||||
object IvyPatternParserTests extends TestSuite {
|
||||
|
||||
val tests = TestSuite {
|
||||
val tests = Tests {
|
||||
|
||||
'plugin - {
|
||||
val strPattern = "[organization]/[module](/scala_[scalaVersion])(/sbt_[sbtVersion])/[revision]/resolved.xml.[ext]"
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ object ParseTests extends TestSuite {
|
|||
|
||||
val url = "file%3A%2F%2Fsome%2Fencoded%2Furl"
|
||||
|
||||
val tests = TestSuite {
|
||||
val tests = Tests {
|
||||
"bintray-ivy:" - {
|
||||
val obtained = Parse.repository("bintray-ivy:scalameta/maven")
|
||||
assert(obtained.right.exists(isIvyRepo))
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import utest._
|
|||
|
||||
object PomParsingTests extends TestSuite {
|
||||
|
||||
val tests = TestSuite {
|
||||
val tests = Tests {
|
||||
'readClassifier{
|
||||
val depNode ="""
|
||||
<dependency>
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ object ResolutionTests extends TestSuite {
|
|||
Resolution(deps, filter = filter, forceVersions = forceVersions)
|
||||
.process
|
||||
.run(Platform.fetch(repositories))
|
||||
.runF
|
||||
.future()
|
||||
|
||||
implicit class ProjectOps(val p: Project) extends AnyVal {
|
||||
def kv: (ModuleVersion, (Artifact.Source, Project)) = p.moduleVersion -> (testRepository.source, p)
|
||||
|
|
@ -206,7 +206,7 @@ object ResolutionTests extends TestSuite {
|
|||
testRepository
|
||||
)
|
||||
|
||||
val tests = TestSuite {
|
||||
val tests = Tests {
|
||||
'empty{
|
||||
async{
|
||||
val res = await(resolve0(
|
||||
|
|
|
|||
|
|
@ -4,8 +4,6 @@ package test
|
|||
import coursier.core._
|
||||
import coursier.util.{EitherT, Monad}
|
||||
|
||||
import scala.language.higherKinds
|
||||
|
||||
final case class TestRepository(projects: Map[(Module, String), Project]) extends Repository {
|
||||
val source = new core.Artifact.Source {
|
||||
def artifacts(
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import utest._
|
|||
|
||||
object VersionConstraintTests extends TestSuite {
|
||||
|
||||
val tests = TestSuite {
|
||||
val tests = Tests {
|
||||
'parse{
|
||||
'empty{
|
||||
val c0 = Parse.versionConstraint("")
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ object VersionTests extends TestSuite {
|
|||
versions.iterator.sliding(2).withPartial(false).forall{case Seq(a, b) => compare(a, b) < 0 }
|
||||
|
||||
|
||||
val tests = TestSuite {
|
||||
val tests = Tests {
|
||||
|
||||
'stackOverflow - {
|
||||
val s = "." * 100000
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import utest._
|
|||
|
||||
object PrintTests extends TestSuite {
|
||||
|
||||
val tests = TestSuite {
|
||||
val tests = Tests {
|
||||
'ignoreAttributes - {
|
||||
val dep = Dependency(
|
||||
Module("org", "name"),
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ object TreeTests extends TestSuite {
|
|||
e.addChild(f)
|
||||
|
||||
|
||||
val tests = TestSuite {
|
||||
val tests = Tests {
|
||||
'basic {
|
||||
val str = Tree[Node](roots)(_.children, _.label)
|
||||
assert(str ==
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
package coursier
|
||||
package web
|
||||
package coursier.web
|
||||
|
||||
import coursier.{Dependency, Fetch, MavenRepository, Module, Platform, Repository, Resolution}
|
||||
import coursier.maven.MavenSource
|
||||
|
||||
import coursier.util.{Gather, Task}
|
||||
import japgolly.scalajs.react.vdom.{ TagMod, Attr }
|
||||
import japgolly.scalajs.react.vdom.Attrs.dangerouslySetInnerHtml
|
||||
import japgolly.scalajs.react.{ ReactEventI, ReactComponentB, BackendScope }
|
||||
|
|
@ -34,11 +34,11 @@ final case class State(
|
|||
class Backend($: BackendScope[Unit, State]) {
|
||||
|
||||
def fetch(
|
||||
repositories: Seq[core.Repository],
|
||||
repositories: Seq[Repository],
|
||||
fetch: Fetch.Content[Task]
|
||||
): Fetch.Metadata[Task] = {
|
||||
|
||||
modVers => Task.gatherUnordered(
|
||||
modVers => Gather[Task].gather(
|
||||
modVers.map { case (module, version) =>
|
||||
Fetch.find(repositories, module, version, fetch)
|
||||
.run
|
||||
|
|
@ -112,8 +112,8 @@ class Backend($: BackendScope[Unit, State]) {
|
|||
.get(dep.moduleVersion)
|
||||
.toSeq
|
||||
.flatMap{case (_, proj) =>
|
||||
core.Resolution.finalDependencies(dep, proj)
|
||||
.filter(resolution.filter getOrElse core.Resolution.defaultFilter)
|
||||
coursier.core.Resolution.finalDependencies(dep, proj)
|
||||
.filter(resolution.filter getOrElse coursier.core.Resolution.defaultFilter)
|
||||
}
|
||||
|
||||
val minDependencies = resolution.minDependencies
|
||||
|
|
@ -185,7 +185,7 @@ class Backend($: BackendScope[Unit, State]) {
|
|||
|
||||
// For reasons that are unclear to me, not delaying this when using the runNow execution context
|
||||
// somehow discards the $.modState above. (Not a major problem as queue is used by default.)
|
||||
Future(task)(scala.scalajs.concurrent.JSExecutionContext.Implicits.queue).flatMap(_.runF).foreach { res: Resolution =>
|
||||
Future(task)(scala.scalajs.concurrent.JSExecutionContext.Implicits.queue).flatMap(_.future()).foreach { res: Resolution =>
|
||||
$.modState{ s =>
|
||||
updateDepGraph(res)
|
||||
updateTree(res, "#deptree", reverse = s.reverseTree)
|
||||
|
|
|
|||
Loading…
Reference in New Issue