diff --git a/.travis.yml b/.travis.yml index abb2ca399..17d74437d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,6 +10,9 @@ install: - npm install xhr2 script: project/travis.sh "$TRAVIS_SCALA_VERSION" "$TRAVIS_PULL_REQUEST" "$TRAVIS_BRANCH" "$(jdk_switcher home oraclejdk7)" +# Uncomment once https://github.com/scoverage/sbt-scoverage/issues/111 is fixed +# after_success: +# - bash <(curl -s https://codecov.io/bash) env: global: - secure: miHFMwVRD/yjOLy794nOwc2lJTMyL5O0MXABT9ksg5ejQy1FrFVc2YH86Agp80W02/lGLGl0qWCiK1TBcs9q4Apt01nkD1a/0/iuTRm//bdhnu8BbRxFITf+2cyYJVytKPsF585aHldMv1rwZs3TDaTzEEecAEki5r50yyTVo7ycG0lVj9aVWXerKRMIT54Wb8M6nqbyRB1jGWT0ETNU13vOvQznPTUXQG5hsiKnGYRf8T3umOMdOHpV0rvdwYqAIMsikaAFcYCS5P/pLXMtmRHICH9KUG8TV/ST07p1BXtbBg9y1Q+lpnXotXh4ZNoWOp8B6v7fxJ/WlLYTDROWCiHJ4s2V4Di00db/nW4OWrEEBlrh7vJ/npZqyt9V9YeNv6alxi+DCESwusgvD4Cx5c3zh+2X6RB6BYwWHlFnd80rmsLe4R4fFUcc8E/ZR9vUFjP1CsQKqfJ5yfKR6V+n8jK8FjLpoaU9PHPo2H4V3FZM/fCLcxhE37vfaYI7/O7MqE/cdGpZIuz7g3c4toWCgNZJDn8iJCPmrgcbW5zbfDxvWU2K816ycgnUwSQ5dufrJpAbLNrjR1O8EPRkMDDp9bB7/4RVQvfDfP9GGoiHPHHgxGzY0Lf5bm+Bj1mRfB5/SXHd3IjhUCD9q7eD1/ANifEYALC5BJ4TB8RhQUPU8uM= diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 000000000..160fd34e3 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,23 @@ +# Adapted from https://github.com/sbt/sbt-native-packager/blob/master/appveyor.yml +version: '{build}' +os: Windows Server 2012 +install: + - ps: | + Add-Type -AssemblyName System.IO.Compression.FileSystem + if (!(Test-Path -Path "C:\sbt" )) { + (new-object System.Net.WebClient).DownloadFile( + 'https://dl.bintray.com/sbt/native-packages/sbt/0.13.8/sbt-0.13.8.zip', + 'C:\sbt-bin.zip' + ) + [System.IO.Compression.ZipFile]::ExtractToDirectory("C:\sbt-bin.zip", "C:\sbt") + } + - cmd: SET PATH=C:\sbt\sbt\bin;%JAVA_HOME%\bin;%PATH% + - cmd: SET SBT_OPTS=-XX:MaxPermSize=2g -Xmx4g +build_script: + - sbt clean compile publish-local +test_script: + - sbt core-jvm/test # Would node be around for core-js/test? +cache: + - C:\sbt\ + - C:\Users\appveyor\.m2 + - C:\Users\appveyor\.ivy2 diff --git a/cli/src/main/scala/coursier/cli/Coursier.scala b/cli/src/main/scala/coursier/cli/Coursier.scala index da6584b85..1e7b8620e 100644 --- a/cli/src/main/scala/coursier/cli/Coursier.scala +++ b/cli/src/main/scala/coursier/cli/Coursier.scala @@ -10,20 +10,42 @@ import scalaz.{ \/-, -\/ } import scalaz.concurrent.Task case class Coursier( - scope: List[String], - keepOptional: Boolean, - fetch: Boolean, - @ExtraName("J") default: Boolean, - @ExtraName("S") sources: Boolean, - @ExtraName("D") javadoc: Boolean, - @ExtraName("P") @ExtraName("cp") classpath: Boolean, - @ExtraName("c") offline: Boolean, - @ExtraName("f") force: Boolean, - @ExtraName("q") quiet: Boolean, - @ExtraName("v") verbose: List[Unit], - @ExtraName("N") maxIterations: Int = 100, - @ExtraName("r") repository: List[String], - @ExtraName("n") parallel: Option[Int] + @HelpMessage("Keep optional dependencies (Maven)") + keepOptional: Boolean, + @HelpMessage("Fetch main artifacts (default: true if --classpath is specified and sources and javadoc are not fetched, else false)") + @ExtraName("J") + default: Boolean, + @HelpMessage("Fetch source artifacts") + @ExtraName("S") + sources: Boolean, + @HelpMessage("Fetch javadoc artifacts") + @ExtraName("D") + javadoc: Boolean, + @HelpMessage("Print java -cp compatible classpath (use like java -cp $(coursier -P ..dependencies..) )") + @ExtraName("P") + @ExtraName("cp") + classpath: Boolean, + @HelpMessage("Off-line mode: only use cache and local repositories") + @ExtraName("c") + offline: Boolean, + @HelpMessage("Force download: for remote repositories only: re-download items, that is, don't use cache directly") + @ExtraName("f") + force: Boolean, + @HelpMessage("Quiet output") + @ExtraName("q") + quiet: Boolean, + @HelpMessage("Increase verbosity (specify several times to increase more)") + @ExtraName("v") + verbose: List[Unit], + @HelpMessage("Maximum number of resolution iterations (specify a negative value for unlimited, default: 100)") + @ExtraName("N") + maxIterations: Int = 100, + @HelpMessage("Repositories - for multiple repositories, separate with comma and/or repeat this option (e.g. -r central,ivy2local -r sonatype-snapshots, or equivalently -r central,ivy2local,sonatype-snapshots)") + @ExtraName("r") + repository: List[String], + @HelpMessage("Maximim number of parallel downloads (default: 6)") + @ExtraName("n") + parallel: Int = 6 ) extends App { val verbose0 = { @@ -31,11 +53,6 @@ case class Coursier( (if (quiet) 1 else 0) } - val scopes0 = - if (scope.isEmpty) List(Scope.Compile, Scope.Runtime) - else scope.map(Parse.scope) - val scopes = scopes0.toSet - def fileRepr(f: File) = f.toString def println(s: String) = Console.err.println(s) @@ -46,6 +63,10 @@ case class Coursier( sys.exit(255) } + if (parallel <= 0) { + println(s"Error: invalid --parallel (-n) value: $parallel") + } + def defaultLogger: MavenRepository.Logger with Files.Logger = new MavenRepository.Logger with Files.Logger { @@ -170,7 +191,7 @@ case class Coursier( val startRes = Resolution( deps.toSet, - filter = Some(dep => (keepOptional || !dep.optional) && scopes(dep.scope)) + filter = Some(dep => keepOptional || !dep.optional) ) val fetchQuiet = coursier.fetch(repositories) @@ -200,18 +221,44 @@ case class Coursier( def repr(dep: Dependency) = { // dep.version can be an interval, whereas the one from project can't - val version = res.projectCache.get(dep.moduleVersion).map(_._2.version).getOrElse(dep.version) + val version = res + .projectCache + .get(dep.moduleVersion) + .map(_._2.version) + .getOrElse(dep.version) val extra = if (version == dep.version) "" else s" ($version for ${dep.version})" - s"${dep.module.organization}:${dep.module.name}:${dep.attributes.`type`}:${Some(dep.attributes.classifier).filter(_.nonEmpty).map(_+":").mkString}$version$extra" + ( + Seq( + dep.module.organization, + dep.module.name, + dep.attributes.`type` + ) ++ + Some(dep.attributes.classifier) + .filter(_.nonEmpty) + .toSeq ++ + Seq( + version + ) + ).mkString(":") + extra } - val trDeps = res.minDependencies.toList.sortBy(repr) + val trDeps = res + .minDependencies + .toList + .sortBy(repr) - if (verbose0 >= 0) - println("\n" + trDeps.map(repr).distinct.mkString("\n")) + if (verbose0 >= 0) { + println("") + println( + trDeps + .map(repr) + .distinct + .mkString("\n") + ) + } if (res.conflicts.nonEmpty) { // Needs test @@ -226,7 +273,7 @@ case class Coursier( } } - if (fetch || classpath) { + if (classpath || default || sources || javadoc) { println("") val artifacts0 = res.artifacts @@ -248,8 +295,7 @@ case class Coursier( var files0 = cache .files() .copy(logger = logger) - for (n <- parallel if n > 0) - files0 = files0.copy(concurrentDownloadCount = n) + files0 = files0.copy(concurrentDownloadCount = parallel) files0 } diff --git a/core/src/main/scala/coursier/core/Resolution.scala b/core/src/main/scala/coursier/core/Resolution.scala index 6456b40c3..3b19714eb 100644 --- a/core/src/main/scala/coursier/core/Resolution.scala +++ b/core/src/main/scala/coursier/core/Resolution.scala @@ -359,10 +359,10 @@ object Resolution { /** * Default dependency filter used during resolution. * - * Only follows compile scope / non-optional dependencies. + * Does not follow optional dependencies. */ def defaultFilter(dep: Dependency): Boolean = - !dep.optional && dep.scope == Scope.Compile + !dep.optional } diff --git a/core/src/test/resources/resolutions/com.github.fommil:java-logging:1.2-SNAPSHOT b/core/src/test/resources/resolutions/com.github.fommil:java-logging:1.2-SNAPSHOT new file mode 100644 index 000000000..32fa7fc99 --- /dev/null +++ b/core/src/test/resources/resolutions/com.github.fommil:java-logging:1.2-SNAPSHOT @@ -0,0 +1,5 @@ +com.github.fommil:java-logging:jar:1.2-SNAPSHOT +org.slf4j:jcl-over-slf4j:jar:1.7.5 +org.slf4j:log4j-over-slf4j:jar:1.7.5 +org.slf4j:slf4j-api:jar:1.7.5 +org.slf4j:slf4j-jdk14:jar:1.7.5 diff --git a/core/src/test/scala/coursier/test/CentralTests.scala b/core/src/test/scala/coursier/test/CentralTests.scala index 82ee9cd62..e3339a740 100644 --- a/core/src/test/scala/coursier/test/CentralTests.scala +++ b/core/src/test/scala/coursier/test/CentralTests.scala @@ -1,9 +1,9 @@ package coursier package test -import coursier.core.Repository +import coursier.core.{ Repository, MavenRepository } import utest._ -import scala.async.Async.{async, await} +import scala.async.Async.{ async, await } import coursier.test.compatibility._ @@ -15,26 +15,56 @@ object CentralTests extends TestSuite { implicit val cachePolicy = CachePolicy.Default - def resolve(deps: Set[Dependency], filter: Option[Dependency => Boolean] = None, extraRepo: Option[Repository] = None) = { + def resolve( + deps: Set[Dependency], + filter: Option[Dependency => Boolean] = None, + extraRepo: Option[Repository] = None + ) = { val repositories0 = extraRepo.toSeq ++ repositories Resolution(deps, filter = filter) .process - .run(fetch(repositories0)) + .run(repositories0) .runF } def repr(dep: Dependency) = - s"${dep.module.organization}:${dep.module.name}:${dep.attributes.`type`}:${Some(dep.attributes.classifier).filter(_.nonEmpty).map(_+":").mkString}${dep.version}" + ( + Seq( + dep.module.organization, + dep.module.name, + dep.attributes.`type` + ) ++ + Some(dep.attributes.classifier) + .filter(_.nonEmpty) + .toSeq ++ + Seq( + dep.version + ) + ).mkString(":") - def resolutionCheck(module: Module, version: String, extraRepo: Option[Repository] = None) = + def resolutionCheck( + module: Module, + version: String, + extraRepo: Option[Repository] = None + ) = async { - val expected = await(textResource(s"resolutions/${module.organization}:${module.name}:$version")).split('\n').toSeq + val expected = + await( + textResource(s"resolutions/${module.organization}:${module.name}:$version") + ) + .split('\n') + .toSeq val dep = Dependency(module, version) val res = await(resolve(Set(dep), extraRepo = extraRepo)) - val result = res.dependencies.toVector.map(repr).sorted.distinct + val result = res + .dependencies + .toVector + .map(repr) + .sorted + .distinct for (((e, r), idx) <- expected.zip(result).zipWithIndex if e != r) println(s"Line $idx:\n expected: $e\n got:$r") @@ -94,10 +124,24 @@ object CentralTests extends TestSuite { } } 'spark{ - resolutionCheck(Module("org.apache.spark", "spark-core_2.11"), "1.3.1") + resolutionCheck( + Module("org.apache.spark", "spark-core_2.11"), + "1.3.1" + ) } 'argonautShapeless{ - resolutionCheck(Module("com.github.alexarchambault", "argonaut-shapeless_6.1_2.11"), "0.2.0") + resolutionCheck( + Module("com.github.alexarchambault", "argonaut-shapeless_6.1_2.11"), + "0.2.0" + ) + } + 'snapshotMetadata{ + // Let's hope this one won't change too much + resolutionCheck( + Module("com.github.fommil", "java-logging"), + "1.2-SNAPSHOT", + extraRepo = Some(MavenRepository("https://oss.sonatype.org/content/repositories/public/")) + ) } } diff --git a/project/plugins.sbt b/project/plugins.sbt index 556b5cc83..97c689d78 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -5,3 +5,5 @@ addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.3") addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.0.0") addSbtPlugin("com.github.gseitz" % "sbt-release" % "0.8.5") + +addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.1.0") diff --git a/project/travis.sh b/project/travis.sh index afc5b5c77..e18038e87 100755 --- a/project/travis.sh +++ b/project/travis.sh @@ -34,8 +34,12 @@ else SBT_COMMANDS="compile" fi -sbt ++2.11.6 core-jvm/publish-local # Required for ~/.ivy2/local repo tests -SBT_COMMANDS="$SBT_COMMANDS core-jvm/test core-js/test" +# Required for ~/.ivy2/local repo tests +sbt ++2.11.6 core-jvm/publish-local + +SBT_COMMANDS="$SBT_COMMANDS test" + +# TODO Add coverage once https://github.com/scoverage/sbt-scoverage/issues/111 is fixed PUSH_GHPAGES=0 if isNotPr && isJdk7 && isMaster; then