mirror of https://github.com/sbt/sbt.git
Merge pull request #426 from alexarchambault/topic/shading
Add shading plugin
This commit is contained in:
commit
12a7419636
|
|
@ -28,7 +28,7 @@ function isMasterOrDevelop() {
|
|||
}
|
||||
|
||||
# Required for ~/.ivy2/local repo tests
|
||||
~/sbt coreJVM/publishLocal http-server/publishLocal
|
||||
~/sbt ++2.11.8 coreJVM/publishLocal http-server/publishLocal
|
||||
|
||||
# Required for HTTP authentication tests
|
||||
./coursier launch \
|
||||
|
|
@ -43,9 +43,33 @@ function isMasterOrDevelop() {
|
|||
|
||||
SBT_COMMANDS="compile test it:test"
|
||||
|
||||
RUN_SHADING_TESTS=1
|
||||
|
||||
if echo "$TRAVIS_SCALA_VERSION" | grep -q "^2\.10"; then
|
||||
SBT_COMMANDS="$SBT_COMMANDS publishLocal" # to make the scripted tests happy
|
||||
SBT_COMMANDS="$SBT_COMMANDS plugin/scripted"
|
||||
|
||||
if [ "$RUN_SHADING_TESTS" = 1 ]; then
|
||||
# for the shading scripted test
|
||||
sudo cp coursier /usr/local/bin/
|
||||
|
||||
JARJAR_VERSION=1.0.1-coursier-SNAPSHOT
|
||||
|
||||
if [ ! -d "$HOME/.m2/repository/org/anarres/jarjar/jarjar-core/$JARJAR_VERSION" ]; then
|
||||
git clone https://github.com/alexarchambault/jarjar.git
|
||||
cd jarjar
|
||||
if ! grep -q "^version=$JARJAR_VERSION\$" gradle.properties; then
|
||||
echo "Expected jarjar version not found" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
git checkout 249c8dbb970f8
|
||||
./gradlew :jarjar-core:install
|
||||
cd ..
|
||||
rm -rf jarjar
|
||||
fi
|
||||
|
||||
SBT_COMMANDS="$SBT_COMMANDS plugin/publishLocal sbt-shading/scripted"
|
||||
fi
|
||||
fi
|
||||
|
||||
SBT_COMMANDS="$SBT_COMMANDS tut coreJVM/mimaReportBinaryIssues cache/mimaReportBinaryIssues"
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ script:
|
|||
# - bash <(curl -s https://codecov.io/bash)
|
||||
matrix:
|
||||
include:
|
||||
- env: TRAVIS_SCALA_VERSION=2.12.0 PUBLISH=1
|
||||
- env: TRAVIS_SCALA_VERSION=2.12.1 PUBLISH=1
|
||||
os: linux
|
||||
jdk: oraclejdk8
|
||||
- env: TRAVIS_SCALA_VERSION=2.11.8 PUBLISH=1
|
||||
|
|
@ -36,3 +36,9 @@ env:
|
|||
branches:
|
||||
only:
|
||||
- master
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.m2
|
||||
- $HOME/.ivy2/cache
|
||||
- $HOME/.sbt
|
||||
# Not adding $HOME/.coursier, we check that sbt-coursier works fine with an initially empty cache
|
||||
|
|
|
|||
15
appveyor.yml
15
appveyor.yml
|
|
@ -14,15 +14,24 @@ install:
|
|||
- cmd: SET PATH=C:\sbt\sbt\bin;%JAVA_HOME%\bin;%PATH%
|
||||
- cmd: SET SBT_OPTS=-XX:MaxPermSize=2g -Xmx4g
|
||||
- cmd: SET COURSIER_NO_TERM=1
|
||||
- ps: |
|
||||
if (!(Test-Path 'C:\Users\appveyor\.m2\repository\org\anarres\jarjar\jarjar-core\1.0.1-coursier-SNAPSHOT')) {
|
||||
iex 'git clone https://github.com/alexarchambault/jarjar'
|
||||
Set-Location -Path jarjar
|
||||
iex 'git checkout 249c8dbb970f8'
|
||||
iex './gradlew.bat :jarjar-core:install'
|
||||
Set-Location -Path ..
|
||||
}
|
||||
build_script:
|
||||
- sbt ++2.11.8 clean compile coreJVM/publishLocal http-server/publishLocal
|
||||
- sbt ++2.10.6 clean compile
|
||||
- sbt ++2.10.6 coreJVM/publishLocal cache/publishLocal # to make the scripted tests happy
|
||||
test_script:
|
||||
- ps: Start-Job { & java -jar -noverify C:\projects\coursier\coursier launch -r http://dl.bintray.com/scalaz/releases io.get-coursier:http-server-java7_2.11:1.0.0-SNAPSHOT -- -d /C:/projects/coursier/tests/jvm/src/test/resources/test-repo/http/abc.com -u user -P pass -r realm -v }
|
||||
- sbt ++2.12.0 testsJVM/test testsJVM/it:test # Would node be around for testsJS/test?
|
||||
- sbt ++2.12.1 testsJVM/test testsJVM/it:test # Would node be around for testsJS/test?
|
||||
- sbt ++2.11.8 testsJVM/test testsJVM/it:test
|
||||
- sbt ++2.10.6 testsJVM/test testsJVM/it:test plugin/scripted
|
||||
- sbt ++2.10.6 testsJVM/test testsJVM/it:test plugin/scripted plugin/publishLocal sbt-shading/scripted
|
||||
cache:
|
||||
- C:\Users\appveyor\.ivy2
|
||||
- C:\Users\appveyor\.ivy2\cache
|
||||
- C:\Users\appveyor\.m2
|
||||
- C:\Users\appveyor\.sbt
|
||||
|
|
|
|||
455
build.sbt
455
build.sbt
|
|
@ -1,137 +1,29 @@
|
|||
import java.io.FileOutputStream
|
||||
|
||||
import com.typesafe.tools.mima.plugin.MimaPlugin.mimaDefaultSettings
|
||||
|
||||
val binaryCompatibilityVersion = "1.0.0-M7"
|
||||
val binaryCompatibilityVersion = "1.0.0-M14"
|
||||
val binaryCompatibility212Version = "1.0.0-M15"
|
||||
|
||||
lazy val IntegrationTest = config("it") extend Test
|
||||
|
||||
lazy val releaseSettings = Seq(
|
||||
publishMavenStyle := true,
|
||||
licenses := Seq("Apache 2.0" -> url("http://opensource.org/licenses/Apache-2.0")),
|
||||
homepage := Some(url("https://github.com/alexarchambault/coursier")),
|
||||
scmInfo := Some(ScmInfo(
|
||||
url("https://github.com/alexarchambault/coursier.git"),
|
||||
"scm:git:github.com/alexarchambault/coursier.git",
|
||||
Some("scm:git:git@github.com:alexarchambault/coursier.git")
|
||||
)),
|
||||
pomExtra := {
|
||||
<developers>
|
||||
<developer>
|
||||
<id>alexarchambault</id>
|
||||
<name>Alexandre Archambault</name>
|
||||
<url>https://github.com/alexarchambault</url>
|
||||
</developer>
|
||||
</developers>
|
||||
},
|
||||
publishTo := {
|
||||
val nexus = "https://oss.sonatype.org/"
|
||||
if (isSnapshot.value)
|
||||
Some("snapshots" at nexus + "content/repositories/snapshots")
|
||||
else
|
||||
Some("releases" at nexus + "service/local/staging/deploy/maven2")
|
||||
},
|
||||
credentials ++= {
|
||||
Seq("SONATYPE_USER", "SONATYPE_PASS").map(sys.env.get) match {
|
||||
case Seq(Some(user), Some(pass)) =>
|
||||
Seq(Credentials("Sonatype Nexus Repository Manager", "oss.sonatype.org", user, pass))
|
||||
case _ =>
|
||||
Seq()
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
lazy val noPublishSettings = Seq(
|
||||
publish := (),
|
||||
publishLocal := (),
|
||||
publishArtifact := false
|
||||
)
|
||||
|
||||
def noPublishForScalaVersionSettings(sbv: String*) = Seq(
|
||||
publish := {
|
||||
if (sbv.contains(scalaBinaryVersion.value))
|
||||
()
|
||||
else
|
||||
publish.value
|
||||
},
|
||||
publishLocal := {
|
||||
if (sbv.contains(scalaBinaryVersion.value))
|
||||
()
|
||||
else
|
||||
publishLocal.value
|
||||
},
|
||||
publishArtifact := {
|
||||
if (sbv.contains(scalaBinaryVersion.value))
|
||||
false
|
||||
else
|
||||
publishArtifact.value
|
||||
}
|
||||
)
|
||||
|
||||
lazy val scalaVersionAgnosticCommonSettings = Seq(
|
||||
organization := "io.get-coursier",
|
||||
resolvers ++= Seq(
|
||||
"Scalaz Bintray Repo" at "http://dl.bintray.com/scalaz/releases",
|
||||
Resolver.sonatypeRepo("releases")
|
||||
),
|
||||
scalacOptions ++= {
|
||||
scalaBinaryVersion.value match {
|
||||
case "2.10" | "2.11" =>
|
||||
Seq("-target:jvm-1.6")
|
||||
case _ =>
|
||||
Seq()
|
||||
}
|
||||
},
|
||||
javacOptions ++= {
|
||||
scalaBinaryVersion.value match {
|
||||
case "2.10" | "2.11" =>
|
||||
Seq(
|
||||
"-source", "1.6",
|
||||
"-target", "1.6"
|
||||
)
|
||||
case _ =>
|
||||
Seq()
|
||||
}
|
||||
},
|
||||
javacOptions in Keys.doc := Seq()
|
||||
) ++ releaseSettings
|
||||
|
||||
lazy val commonSettings = scalaVersionAgnosticCommonSettings ++ Seq(
|
||||
scalaVersion := "2.11.8",
|
||||
crossScalaVersions := Seq("2.12.0", "2.11.8", "2.10.6"),
|
||||
libraryDependencies ++= {
|
||||
if (scalaBinaryVersion.value == "2.10")
|
||||
Seq(compilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross CrossVersion.full))
|
||||
else
|
||||
Seq()
|
||||
}
|
||||
)
|
||||
|
||||
val scalazVersion = "7.2.7"
|
||||
lazy val scalazVersion = "7.2.8"
|
||||
|
||||
lazy val core = crossProject
|
||||
.settings(commonSettings: _*)
|
||||
.settings(mimaDefaultSettings: _*)
|
||||
.settings(commonSettings)
|
||||
.settings(mimaPreviousArtifactSettings)
|
||||
.settings(
|
||||
name := "coursier",
|
||||
libraryDependencies ++= Seq(
|
||||
"org.scalaz" %%% "scalaz-core" % scalazVersion,
|
||||
"com.lihaoyi" %%% "fastparse" % "0.4.2"
|
||||
),
|
||||
mimaPreviousArtifacts := {
|
||||
scalaBinaryVersion.value match {
|
||||
case "2.10" | "2.11" =>
|
||||
Set("com.github.alexarchambault" %% moduleName.value % binaryCompatibilityVersion)
|
||||
case _ =>
|
||||
Set()
|
||||
}
|
||||
},
|
||||
mimaBinaryIssueFilters ++= {
|
||||
import com.typesafe.tools.mima.core._
|
||||
|
||||
Seq(
|
||||
// Since 1.0.0-M15
|
||||
// reworked profile activation
|
||||
ProblemFilters.exclude[IncompatibleResultTypeProblem]("coursier.package#Resolution.apply$default$9"),
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.package#Resolution.apply"),
|
||||
ProblemFilters.exclude[IncompatibleResultTypeProblem]("coursier.core.Resolution.copy$default$9"),
|
||||
ProblemFilters.exclude[IncompatibleResultTypeProblem]("coursier.core.Resolution.copyWithCache$default$8"),
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.core.Resolution.copy"),
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.core.Resolution.profileActivation"),
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.core.Resolution.copyWithCache"),
|
||||
|
|
@ -141,81 +33,18 @@ lazy val core = crossProject
|
|||
ProblemFilters.exclude[MissingTypesProblem]("coursier.core.Activation$"),
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.core.Activation.apply"),
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.core.Resolution.profiles"),
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.core.Resolution.apply"),
|
||||
// Since 1.0.0-M13
|
||||
// reworked VersionConstraint
|
||||
ProblemFilters.exclude[MissingClassProblem]("coursier.core.VersionConstraint$Interval"),
|
||||
ProblemFilters.exclude[MissingClassProblem]("coursier.core.VersionConstraint$Preferred"),
|
||||
ProblemFilters.exclude[MissingClassProblem]("coursier.core.VersionConstraint$Preferred$"),
|
||||
ProblemFilters.exclude[MissingClassProblem]("coursier.core.VersionConstraint$Interval$"),
|
||||
ProblemFilters.exclude[FinalClassProblem]("coursier.core.VersionConstraint"),
|
||||
ProblemFilters.exclude[IncompatibleResultTypeProblem]("coursier.core.VersionConstraint.repr"),
|
||||
ProblemFilters.exclude[IncompatibleMethTypeProblem]("coursier.core.VersionConstraint.this"),
|
||||
// Extra `actualVersion` field in `Project`
|
||||
ProblemFilters.exclude[MissingTypesProblem]("coursier.core.Project$"),
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.core.Project.apply"),
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.core.Project.copy"),
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.core.Project.this"),
|
||||
// Reworked Ivy pattern handling
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.ivy.Pattern.pattern"),
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.ivy.Pattern.copy"),
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.ivy.Pattern.properties"),
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.ivy.Pattern.parts"),
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.ivy.Pattern.substitute"),
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.ivy.Pattern.this"),
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.ivy.Pattern.substituteProperties"),
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.ivy.Pattern.propertyRegex"),
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.ivy.Pattern.apply"),
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.ivy.Pattern.variableRegex"),
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.ivy.Pattern.optionalPartRegex"),
|
||||
ProblemFilters.exclude[MissingClassProblem]("coursier.ivy.Pattern$PatternPart$Literal$"),
|
||||
ProblemFilters.exclude[MissingClassProblem]("coursier.ivy.Pattern$PatternPart"),
|
||||
ProblemFilters.exclude[MissingClassProblem]("coursier.ivy.Pattern$PatternPart$"),
|
||||
ProblemFilters.exclude[IncompatibleMethTypeProblem]("coursier.ivy.IvyRepository.apply"),
|
||||
ProblemFilters.exclude[MissingClassProblem]("coursier.ivy.Pattern$PatternPart$Optional$"),
|
||||
ProblemFilters.exclude[MissingClassProblem]("coursier.ivy.Pattern$PatternPart$Literal"),
|
||||
ProblemFilters.exclude[MissingClassProblem]("coursier.ivy.Pattern$PatternPart$Optional"),
|
||||
ProblemFilters.exclude[IncompatibleResultTypeProblem]("coursier.ivy.IvyRepository.pattern"),
|
||||
ProblemFilters.exclude[IncompatibleMethTypeProblem]("coursier.ivy.IvyRepository.copy"),
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.ivy.IvyRepository.properties"),
|
||||
ProblemFilters.exclude[IncompatibleResultTypeProblem]("coursier.ivy.IvyRepository.metadataPattern"),
|
||||
ProblemFilters.exclude[IncompatibleMethTypeProblem]("coursier.ivy.IvyRepository.this"),
|
||||
ProblemFilters.exclude[IncompatibleResultTypeProblem]("coursier.util.Parse.repository"),
|
||||
// Since 1.0.0-M12
|
||||
// Extra `authentication` field
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.core.Artifact.apply"),
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.core.Artifact.copy"),
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.core.Artifact.this"),
|
||||
ProblemFilters.exclude[MissingTypesProblem]("coursier.ivy.IvyRepository$"),
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.ivy.IvyRepository.apply"),
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.ivy.IvyRepository.copy"),
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.ivy.IvyRepository.this"),
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.maven.MavenRepository.copy"),
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.maven.MavenRepository.this"),
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.maven.MavenSource.apply"),
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.maven.MavenRepository.apply"),
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.maven.MavenSource.copy"),
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.maven.MavenSource.this"),
|
||||
// Since 1.0.0-M11
|
||||
// Extra parameter with default value added, problem for forward compatibility only
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.core.ResolutionProcess.next"),
|
||||
// method made final (for - non critical - tail recursion)
|
||||
ProblemFilters.exclude[FinalMethodProblem]("coursier.core.ResolutionProcess.next"),
|
||||
// Since 1.0.0-M10
|
||||
ProblemFilters.exclude[IncompatibleResultTypeProblem]("coursier.core.Resolution.withParentConfigurations"),
|
||||
// New singleton object, problem for forward compatibility only
|
||||
ProblemFilters.exclude[MissingTypesProblem]("coursier.maven.MavenSource$")
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.core.Resolution.apply")
|
||||
)
|
||||
}
|
||||
)
|
||||
.jvmSettings(
|
||||
libraryDependencies ++=
|
||||
Seq(
|
||||
"org.jsoup" % "jsoup" % "1.9.2"
|
||||
"org.jsoup" % "jsoup" % "1.10.2"
|
||||
) ++ {
|
||||
if (scalaBinaryVersion.value == "2.10") Seq()
|
||||
else Seq(
|
||||
"org.scala-lang.modules" %% "scala-xml" % "1.0.5"
|
||||
"org.scala-lang.modules" %% "scala-xml" % "1.0.6"
|
||||
)
|
||||
},
|
||||
resourceGenerators.in(Compile) += {
|
||||
|
|
@ -260,10 +89,10 @@ lazy val `fetch-js` = project
|
|||
|
||||
lazy val tests = crossProject
|
||||
.dependsOn(core)
|
||||
.settings(commonSettings: _*)
|
||||
.settings(noPublishSettings: _*)
|
||||
.settings(commonSettings)
|
||||
.settings(noPublishSettings)
|
||||
.configs(IntegrationTest)
|
||||
.settings(Defaults.itSettings: _*)
|
||||
.settings(Defaults.itSettings)
|
||||
.settings(
|
||||
name := "coursier-tests",
|
||||
libraryDependencies += {
|
||||
|
|
@ -275,7 +104,7 @@ lazy val tests = crossProject
|
|||
|
||||
"org.scala-lang.modules" %% "scala-async" % asyncVersion % "provided"
|
||||
},
|
||||
libraryDependencies += "com.lihaoyi" %%% "utest" % "0.4.4" % "test",
|
||||
libraryDependencies += "com.lihaoyi" %%% "utest" % "0.4.5" % "test",
|
||||
unmanagedResourceDirectories in Test += (baseDirectory in LocalRootProject).value / "tests" / "shared" / "src" / "test" / "resources",
|
||||
testFrameworks += new TestFramework("utest.runner.Framework")
|
||||
)
|
||||
|
|
@ -289,70 +118,19 @@ lazy val testsJs = tests.js.dependsOn(`fetch-js` % "test")
|
|||
lazy val cache = project
|
||||
.dependsOn(coreJvm)
|
||||
.settings(commonSettings)
|
||||
.settings(mimaDefaultSettings)
|
||||
.settings(mimaPreviousArtifactSettings)
|
||||
.settings(
|
||||
name := "coursier-cache",
|
||||
libraryDependencies += "org.scalaz" %% "scalaz-concurrent" % scalazVersion,
|
||||
mimaPreviousArtifacts := {
|
||||
scalaBinaryVersion.value match {
|
||||
case "2.10" | "2.11" =>
|
||||
Set("com.github.alexarchambault" %% moduleName.value % binaryCompatibilityVersion)
|
||||
case _ =>
|
||||
Set()
|
||||
}
|
||||
},
|
||||
mimaBinaryIssueFilters ++= {
|
||||
import com.typesafe.tools.mima.core._
|
||||
|
||||
Seq(
|
||||
// Since 1.0.0-M13
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.Cache.file"),
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.Cache.fetch"),
|
||||
// Since 1.0.0-M12
|
||||
// Remove deprecated / unused helper method
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.Cache.readFully"),
|
||||
// Since 1.0.0-M11
|
||||
// Add constructor parameter on FileError - shouldn't be built by users anyway
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.FileError.this"),
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.FileError#Recoverable.this"),
|
||||
// Since 1.0.0-M10
|
||||
// methods that should have been private anyway
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.TermDisplay.update"),
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.TermDisplay.fallbackMode_="),
|
||||
// cache argument type changed from `Seq[(String, File)]` to `File`
|
||||
ProblemFilters.exclude[IncompatibleMethTypeProblem]("coursier.Cache.file"),
|
||||
ProblemFilters.exclude[IncompatibleMethTypeProblem]("coursier.Cache.fetch"),
|
||||
ProblemFilters.exclude[IncompatibleResultTypeProblem]("coursier.Cache.default"),
|
||||
ProblemFilters.exclude[IncompatibleMethTypeProblem]("coursier.Cache.validateChecksum"),
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.Cache.defaultBase"),
|
||||
// New methdos in Cache.Logger
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.Cache#Logger.checkingUpdates"),
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.Cache#Logger.checkingUpdatesResult"),
|
||||
// Better overload of Cache.Logger.downloadLength, deprecate previous one
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.Cache#Logger.downloadLength"),
|
||||
// Changes to private class TermDisplay#Info
|
||||
ProblemFilters.exclude[MissingClassProblem]("coursier.TermDisplay$Info$"),
|
||||
ProblemFilters.exclude[AbstractClassProblem]("coursier.TermDisplay$Info"),
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.TermDisplay#Info.downloaded"),
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.TermDisplay#Info.productElement"),
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.TermDisplay#Info.productArity"),
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.TermDisplay#Info.canEqual"),
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.TermDisplay#Info.length"),
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.TermDisplay#Info.display"),
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.TermDisplay#Info.fraction"),
|
||||
// Since 1.0.0-M9
|
||||
// Added an optional extra parameter to FileError.NotFound - only
|
||||
// its unapply method should break compatibility at the source level.
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.FileError#NotFound.copy"),
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.FileError#NotFound.this"),
|
||||
ProblemFilters.exclude[MissingTypesProblem]("coursier.FileError$NotFound$"),
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.FileError#NotFound.apply"),
|
||||
// Since 1.0.0-M8
|
||||
ProblemFilters.exclude[MissingTypesProblem]("coursier.TermDisplay$Info$"),
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.TermDisplay#Info.apply"),
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.TermDisplay#Info.copy"),
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.TermDisplay#Info.pct"),
|
||||
ProblemFilters.exclude[MissingMethodProblem]("coursier.TermDisplay#Info.this")
|
||||
ProblemFilters.exclude[MissingClassProblem]("coursier.TermDisplay$Message$Stop$"),
|
||||
ProblemFilters.exclude[MissingClassProblem]("coursier.TermDisplay$Message"),
|
||||
ProblemFilters.exclude[MissingClassProblem]("coursier.TermDisplay$Message$"),
|
||||
ProblemFilters.exclude[MissingClassProblem]("coursier.TermDisplay$Message$Update$"),
|
||||
ProblemFilters.exclude[MissingClassProblem]("coursier.TermDisplay$UpdateDisplayThread")
|
||||
)
|
||||
}
|
||||
)
|
||||
|
|
@ -384,7 +162,7 @@ lazy val cli = project
|
|||
name := "coursier-cli",
|
||||
libraryDependencies ++= {
|
||||
if (scalaBinaryVersion.value == "2.11")
|
||||
Seq("com.github.alexarchambault" %% "case-app" % "1.1.2")
|
||||
Seq("com.github.alexarchambault" %% "case-app" % "1.1.3")
|
||||
else
|
||||
Seq()
|
||||
},
|
||||
|
|
@ -512,7 +290,7 @@ lazy val web = project
|
|||
libraryDependencies ++= {
|
||||
if (scalaBinaryVersion.value == "2.11")
|
||||
Seq(
|
||||
"be.doeraene" %%% "scalajs-jquery" % "0.9.0",
|
||||
"be.doeraene" %%% "scalajs-jquery" % "0.9.1",
|
||||
"com.github.japgolly.scalajs-react" %%% "core" % "0.9.0"
|
||||
)
|
||||
else
|
||||
|
|
@ -550,28 +328,20 @@ lazy val doc = project
|
|||
// Don't try to compile that if you're not in 2.10
|
||||
lazy val plugin = project
|
||||
.dependsOn(coreJvm, cache)
|
||||
.settings(scalaVersionAgnosticCommonSettings)
|
||||
.settings(noPublishForScalaVersionSettings("2.11", "2.12"))
|
||||
.settings(pluginSettings)
|
||||
.settings(
|
||||
name := "sbt-coursier",
|
||||
sbtPlugin := (scalaBinaryVersion.value == "2.10"),
|
||||
resolvers ++= Seq(
|
||||
// added so that 2.10 artifacts of the other modules can be found by
|
||||
// the too-naive-for-now inter-project resolver of the coursier SBT plugin
|
||||
Resolver.sonatypeRepo("snapshots"),
|
||||
// added for sbt-scripted to be fine even with ++2.11.x
|
||||
Resolver.typesafeIvyRepo("releases")
|
||||
)
|
||||
name := "sbt-coursier"
|
||||
)
|
||||
.settings(ScriptedPlugin.scriptedSettings)
|
||||
|
||||
// Don't try to compile that if you're not in 2.10
|
||||
lazy val `sbt-shading` = project
|
||||
.dependsOn(plugin)
|
||||
.settings(pluginSettings)
|
||||
.settings(
|
||||
scriptedLaunchOpts ++= Seq(
|
||||
"-Xmx1024M",
|
||||
"-XX:MaxPermSize=256M",
|
||||
"-Dplugin.version=" + version.value,
|
||||
"-Dsbttest.base=" + (sourceDirectory.value / "sbt-test").getAbsolutePath
|
||||
),
|
||||
scriptedBufferLog := false
|
||||
// Warning: this version doesn't handle well class names with '$'s
|
||||
// (so basically any Scala library)
|
||||
// See https://github.com/shevek/jarjar/pull/4
|
||||
libraryDependencies += "org.anarres.jarjar" % "jarjar-core" % "1.0.0"
|
||||
)
|
||||
|
||||
val http4sVersion = "0.8.6"
|
||||
|
|
@ -587,8 +357,8 @@ lazy val `http-server` = project
|
|||
Seq(
|
||||
"org.http4s" %% "http4s-blazeserver" % http4sVersion,
|
||||
"org.http4s" %% "http4s-dsl" % http4sVersion,
|
||||
"org.slf4j" % "slf4j-nop" % "1.7.21",
|
||||
"com.github.alexarchambault" %% "case-app" % "1.1.2"
|
||||
"org.slf4j" % "slf4j-nop" % "1.7.22",
|
||||
"com.github.alexarchambault" %% "case-app" % "1.1.3"
|
||||
)
|
||||
else
|
||||
Seq()
|
||||
|
|
@ -606,10 +376,159 @@ lazy val okhttp = project
|
|||
)
|
||||
|
||||
lazy val `coursier` = project.in(file("."))
|
||||
.aggregate(coreJvm, coreJs, `fetch-js`, testsJvm, testsJs, cache, bootstrap, cli, plugin, web, doc, `http-server`, okhttp)
|
||||
.aggregate(
|
||||
coreJvm,
|
||||
coreJs,
|
||||
`fetch-js`,
|
||||
testsJvm,
|
||||
testsJs,
|
||||
cache,
|
||||
bootstrap,
|
||||
cli,
|
||||
plugin,
|
||||
`sbt-shading`,
|
||||
web,
|
||||
doc,
|
||||
`http-server`,
|
||||
okhttp
|
||||
)
|
||||
.settings(commonSettings)
|
||||
.settings(noPublishSettings)
|
||||
.settings(releaseSettings)
|
||||
.settings(
|
||||
moduleName := "coursier-root"
|
||||
)
|
||||
|
||||
lazy val releaseSettings = Seq(
|
||||
publishMavenStyle := true,
|
||||
licenses := Seq("Apache 2.0" -> url("http://opensource.org/licenses/Apache-2.0")),
|
||||
homepage := Some(url("https://github.com/alexarchambault/coursier")),
|
||||
scmInfo := Some(ScmInfo(
|
||||
url("https://github.com/alexarchambault/coursier.git"),
|
||||
"scm:git:github.com/alexarchambault/coursier.git",
|
||||
Some("scm:git:git@github.com:alexarchambault/coursier.git")
|
||||
)),
|
||||
pomExtra := {
|
||||
<developers>
|
||||
<developer>
|
||||
<id>alexarchambault</id>
|
||||
<name>Alexandre Archambault</name>
|
||||
<url>https://github.com/alexarchambault</url>
|
||||
</developer>
|
||||
</developers>
|
||||
},
|
||||
publishTo := {
|
||||
val nexus = "https://oss.sonatype.org/"
|
||||
if (isSnapshot.value)
|
||||
Some("snapshots" at nexus + "content/repositories/snapshots")
|
||||
else
|
||||
Some("releases" at nexus + "service/local/staging/deploy/maven2")
|
||||
},
|
||||
credentials ++= {
|
||||
Seq("SONATYPE_USER", "SONATYPE_PASS").map(sys.env.get) match {
|
||||
case Seq(Some(user), Some(pass)) =>
|
||||
Seq(Credentials("Sonatype Nexus Repository Manager", "oss.sonatype.org", user, pass))
|
||||
case _ =>
|
||||
Seq()
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
lazy val noPublishSettings = Seq(
|
||||
publish := (),
|
||||
publishLocal := (),
|
||||
publishArtifact := false
|
||||
)
|
||||
|
||||
def noPublishForScalaVersionSettings(sbv: String*) = Seq(
|
||||
publish := {
|
||||
if (sbv.contains(scalaBinaryVersion.value))
|
||||
()
|
||||
else
|
||||
publish.value
|
||||
},
|
||||
publishLocal := {
|
||||
if (sbv.contains(scalaBinaryVersion.value))
|
||||
()
|
||||
else
|
||||
publishLocal.value
|
||||
},
|
||||
publishArtifact := {
|
||||
if (sbv.contains(scalaBinaryVersion.value))
|
||||
false
|
||||
else
|
||||
publishArtifact.value
|
||||
}
|
||||
)
|
||||
|
||||
lazy val scalaVersionAgnosticCommonSettings = Seq(
|
||||
organization := "io.get-coursier",
|
||||
resolvers ++= Seq(
|
||||
"Scalaz Bintray Repo" at "http://dl.bintray.com/scalaz/releases",
|
||||
Resolver.sonatypeRepo("releases")
|
||||
),
|
||||
scalacOptions ++= {
|
||||
scalaBinaryVersion.value match {
|
||||
case "2.10" | "2.11" =>
|
||||
Seq("-target:jvm-1.6")
|
||||
case _ =>
|
||||
Seq()
|
||||
}
|
||||
},
|
||||
javacOptions ++= {
|
||||
scalaBinaryVersion.value match {
|
||||
case "2.10" | "2.11" =>
|
||||
Seq(
|
||||
"-source", "1.6",
|
||||
"-target", "1.6"
|
||||
)
|
||||
case _ =>
|
||||
Seq()
|
||||
}
|
||||
},
|
||||
javacOptions in Keys.doc := Seq()
|
||||
) ++ releaseSettings
|
||||
|
||||
lazy val commonSettings = scalaVersionAgnosticCommonSettings ++ Seq(
|
||||
scalaVersion := "2.12.1",
|
||||
crossScalaVersions := Seq("2.12.1", "2.11.8", "2.10.6"),
|
||||
libraryDependencies ++= {
|
||||
if (scalaBinaryVersion.value == "2.10")
|
||||
Seq(compilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross CrossVersion.full))
|
||||
else
|
||||
Seq()
|
||||
}
|
||||
)
|
||||
|
||||
lazy val pluginSettings =
|
||||
scalaVersionAgnosticCommonSettings ++
|
||||
noPublishForScalaVersionSettings("2.11", "2.12") ++
|
||||
ScriptedPlugin.scriptedSettings ++
|
||||
Seq(
|
||||
scriptedLaunchOpts ++= Seq(
|
||||
"-Xmx1024M",
|
||||
"-XX:MaxPermSize=256M",
|
||||
"-Dplugin.version=" + version.value,
|
||||
"-Dsbttest.base=" + (sourceDirectory.value / "sbt-test").getAbsolutePath
|
||||
),
|
||||
scriptedBufferLog := false,
|
||||
sbtPlugin := (scalaBinaryVersion.value == "2.10"),
|
||||
resolvers ++= Seq(
|
||||
// added so that 2.10 artifacts of the other modules can be found by
|
||||
// the too-naive-for-now inter-project resolver of the coursier SBT plugin
|
||||
Resolver.sonatypeRepo("snapshots"),
|
||||
// added for sbt-scripted to be fine even with ++2.11.x
|
||||
Resolver.typesafeIvyRepo("releases")
|
||||
)
|
||||
)
|
||||
|
||||
lazy val mimaPreviousArtifactSettings = Seq(
|
||||
mimaPreviousArtifacts := {
|
||||
val version = scalaBinaryVersion.value match {
|
||||
case "2.12" => binaryCompatibility212Version
|
||||
case _ => binaryCompatibilityVersion
|
||||
}
|
||||
|
||||
Set(organization.value %% moduleName.value % version)
|
||||
}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
@REM https://github.com/xerial/sbt-pack/blob/master/src/main/templates/launch-bat.mustache
|
||||
@REM would be worth getting more inspiration from
|
||||
|
||||
@echo off
|
||||
|
||||
SET ERROR_CODE=0
|
||||
|
||||
SET LAUNCHER_PATH=%~dp0/coursier
|
||||
|
||||
IF NOT EXIST %LAUNCHER_PATH% (
|
||||
bitsadmin /transfer "DownloadCoursierLauncher" https://github.com/alexarchambault/coursier/raw/master/coursier %LAUNCHER_PATH%
|
||||
)
|
||||
|
||||
SET CMD_LINE_ARGS=%*
|
||||
|
||||
java -jar %LAUNCHER_PATH% %CMD_LINE_ARGS%
|
||||
|
||||
IF ERRORLEVEL 1 GOTO error
|
||||
GOTO end
|
||||
|
||||
:error
|
||||
SET ERROR_CODE=1
|
||||
|
||||
:end
|
||||
SET LAUNCHER_PATH=
|
||||
SET CMD_LINE_ARGS=
|
||||
|
||||
EXIT /B %ERROR_CODE%
|
||||
|
||||
|
|
@ -38,6 +38,10 @@ object CoursierPlugin extends AutoPlugin {
|
|||
|
||||
val coursierDependencyTree = Keys.coursierDependencyTree
|
||||
val coursierDependencyInverseTree = Keys.coursierDependencyInverseTree
|
||||
|
||||
val coursierArtifacts = Keys.coursierArtifacts
|
||||
val coursierClassifiersArtifacts = Keys.coursierClassifiersArtifacts
|
||||
val coursierSbtClassifiersArtifacts = Keys.coursierSbtClassifiersArtifacts
|
||||
}
|
||||
|
||||
import autoImport._
|
||||
|
|
@ -51,7 +55,25 @@ object CoursierPlugin extends AutoPlugin {
|
|||
)
|
||||
)
|
||||
|
||||
override lazy val projectSettings = Seq(
|
||||
def makeIvyXmlBefore[T](
|
||||
task: TaskKey[T],
|
||||
shadedConfigOpt: Option[(String, String)]
|
||||
): Setting[Task[T]] =
|
||||
// not 100% sure that make writeFiles below happen before the actions triggered by task.value...
|
||||
task := {
|
||||
val currentProject = {
|
||||
val proj = coursierProject.value
|
||||
val publications = coursierPublications.value
|
||||
proj.copy(publications = publications)
|
||||
}
|
||||
IvyXml.writeFiles(currentProject, shadedConfigOpt, ivySbt.value, streams.value.log)
|
||||
task.value
|
||||
}
|
||||
|
||||
def coursierSettings(
|
||||
shadedConfigOpt: Option[(String, String)],
|
||||
packageConfigs: Seq[(Configuration, String)]
|
||||
) = Seq(
|
||||
coursierParallelDownloads := 6,
|
||||
coursierMaxIterations := 50,
|
||||
coursierDefaultArtifactType := "",
|
||||
|
|
@ -68,27 +90,44 @@ object CoursierPlugin extends AutoPlugin {
|
|||
coursierCredentials := Map.empty,
|
||||
coursierFallbackDependencies <<= Tasks.coursierFallbackDependenciesTask,
|
||||
coursierCache := Cache.default,
|
||||
update <<= Tasks.updateTask(withClassifiers = false),
|
||||
coursierArtifacts <<= Tasks.artifactFilesOrErrors(withClassifiers = false),
|
||||
coursierClassifiersArtifacts <<= Tasks.artifactFilesOrErrors(
|
||||
withClassifiers = true
|
||||
),
|
||||
coursierSbtClassifiersArtifacts <<= Tasks.artifactFilesOrErrors(
|
||||
withClassifiers = true,
|
||||
sbtClassifiers = true
|
||||
),
|
||||
makeIvyXmlBefore(deliverLocalConfiguration, shadedConfigOpt),
|
||||
makeIvyXmlBefore(deliverConfiguration, shadedConfigOpt),
|
||||
update <<= Tasks.updateTask(
|
||||
shadedConfigOpt,
|
||||
withClassifiers = false
|
||||
),
|
||||
updateClassifiers <<= Tasks.updateTask(
|
||||
shadedConfigOpt,
|
||||
withClassifiers = true,
|
||||
ignoreArtifactErrors = true
|
||||
),
|
||||
updateSbtClassifiers in Defaults.TaskGlobal <<= Tasks.updateTask(
|
||||
shadedConfigOpt,
|
||||
withClassifiers = true,
|
||||
sbtClassifiers = true,
|
||||
ignoreArtifactErrors = true
|
||||
),
|
||||
coursierProject <<= Tasks.coursierProjectTask,
|
||||
coursierInterProjectDependencies <<= Tasks.coursierInterProjectDependenciesTask,
|
||||
coursierPublications <<= Tasks.coursierPublicationsTask,
|
||||
coursierPublications <<= Tasks.coursierPublicationsTask(packageConfigs: _*),
|
||||
coursierSbtClassifiersModule <<= classifiersModule in updateSbtClassifiers,
|
||||
coursierConfigurations <<= Tasks.coursierConfigurationsTask,
|
||||
coursierConfigurations <<= Tasks.coursierConfigurationsTask(None),
|
||||
coursierResolution <<= Tasks.resolutionTask(),
|
||||
coursierSbtClassifiersResolution <<= Tasks.resolutionTask(
|
||||
sbtClassifiers = true
|
||||
)
|
||||
) ++
|
||||
inConfig(Compile)(treeSettings) ++
|
||||
inConfig(Test)(treeSettings)
|
||||
)
|
||||
|
||||
}
|
||||
override lazy val projectSettings = coursierSettings(None, Seq(Compile, Test).map(c => c -> c.name)) ++
|
||||
inConfig(Compile)(treeSettings) ++
|
||||
inConfig(Test)(treeSettings)
|
||||
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
package coursier
|
||||
|
||||
import coursier.ivy.{ IvyXml, IvyRepository }
|
||||
import coursier.ivy.IvyRepository
|
||||
import coursier.ivy.IvyXml.{ mappings => ivyXmlMappings }
|
||||
|
||||
import java.net.{ MalformedURLException, URL }
|
||||
|
||||
|
|
@ -71,7 +72,7 @@ object FromSbt {
|
|||
)
|
||||
|
||||
val mapping = module.configurations.getOrElse("compile")
|
||||
val allMappings = IvyXml.mappings(mapping)
|
||||
val allMappings = ivyXmlMappings(mapping)
|
||||
|
||||
val attributes =
|
||||
if (module.explicitArtifacts.isEmpty)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,62 @@
|
|||
package coursier
|
||||
|
||||
import scala.xml.{ Node, PrefixedAttribute }
|
||||
import coursier.internal.FileUtil
|
||||
import org.apache.ivy.core.module.id.ModuleRevisionId
|
||||
|
||||
object MakeIvyXml {
|
||||
import scala.collection.JavaConverters._
|
||||
import scala.xml.{Node, PrefixedAttribute}
|
||||
|
||||
def apply(project: Project): Node = {
|
||||
object IvyXml {
|
||||
|
||||
// These are required for publish to be fine, later on.
|
||||
def writeFiles(
|
||||
currentProject: Project,
|
||||
shadedConfigOpt: Option[(String, String)],
|
||||
ivySbt: sbt.IvySbt,
|
||||
log: sbt.Logger
|
||||
): Unit = {
|
||||
|
||||
val ivyCacheManager = ivySbt.withIvy(log)(ivy =>
|
||||
ivy.getResolutionCacheManager
|
||||
)
|
||||
|
||||
val ivyModule = ModuleRevisionId.newInstance(
|
||||
currentProject.module.organization,
|
||||
currentProject.module.name,
|
||||
currentProject.version,
|
||||
currentProject.module.attributes.asJava
|
||||
)
|
||||
|
||||
val cacheIvyFile = ivyCacheManager.getResolvedIvyFileInCache(ivyModule)
|
||||
val cacheIvyPropertiesFile = ivyCacheManager.getResolvedIvyPropertiesInCache(ivyModule)
|
||||
|
||||
val printer = new scala.xml.PrettyPrinter(80, 2)
|
||||
|
||||
val content0 = """<?xml version="1.0" encoding="UTF-8"?>""" + '\n' +
|
||||
printer.format(content(currentProject, shadedConfigOpt.map(_._2)))
|
||||
cacheIvyFile.getParentFile.mkdirs()
|
||||
log.info(s"Writing Ivy file $cacheIvyFile")
|
||||
FileUtil.write(cacheIvyFile, content0.getBytes("UTF-8"))
|
||||
|
||||
// Just writing an empty file here... Are these only used?
|
||||
cacheIvyPropertiesFile.getParentFile.mkdirs()
|
||||
FileUtil.write(cacheIvyPropertiesFile, Array())
|
||||
}
|
||||
|
||||
def content(project0: Project, shadedConfigOpt: Option[String]): Node = {
|
||||
|
||||
val filterOutDependencies =
|
||||
shadedConfigOpt.toSet[String].flatMap { shadedConfig =>
|
||||
project0
|
||||
.dependencies
|
||||
.collect { case (`shadedConfig`, dep) => dep }
|
||||
}
|
||||
|
||||
val project: Project = project0.copy(
|
||||
dependencies = project0.dependencies.collect {
|
||||
case p @ (_, dep) if !filterOutDependencies(dep) => p
|
||||
}
|
||||
)
|
||||
|
||||
val infoAttrs = project.module.attributes.foldLeft[xml.MetaData](xml.Null) {
|
||||
case (acc, (k, v)) =>
|
||||
|
|
@ -31,11 +83,12 @@ object MakeIvyXml {
|
|||
</info>
|
||||
} % infoAttrs
|
||||
|
||||
val confElems = project.configurations.toVector.map {
|
||||
case (name, extends0) =>
|
||||
val confElems = project.configurations.toVector.collect {
|
||||
case (name, extends0) if shadedConfigOpt != Some(name) =>
|
||||
val extends1 = shadedConfigOpt.fold(extends0)(c => extends0.filter(_ != c))
|
||||
val n = <conf name={name} visibility="public" description="" />
|
||||
if (extends0.nonEmpty)
|
||||
n % <x extends={extends0.mkString(",")} />.attributes
|
||||
if (extends1.nonEmpty)
|
||||
n % <x extends={extends1.mkString(",")} />.attributes
|
||||
else
|
||||
n
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@ import coursier.core.Publication
|
|||
import sbt.{ GetClassifiersModule, Resolver, SettingKey, TaskKey }
|
||||
|
||||
import scala.concurrent.duration.Duration
|
||||
import scalaz.\/
|
||||
|
||||
object Keys {
|
||||
val coursierParallelDownloads = SettingKey[Int]("coursier-parallel-downloads")
|
||||
|
|
@ -51,4 +52,8 @@ object Keys {
|
|||
"coursier-dependency-inverse-tree",
|
||||
"Prints dependencies and transitive dependencies as an inverted tree (dependees as children)"
|
||||
)
|
||||
|
||||
val coursierArtifacts = TaskKey[Map[Artifact, FileError \/ File]]("coursier-artifacts")
|
||||
val coursierClassifiersArtifacts = TaskKey[Map[Artifact, FileError \/ File]]("coursier-classifiers-artifacts")
|
||||
val coursierSbtClassifiersArtifacts = TaskKey[Map[Artifact, FileError \/ File]]("coursier-sbt-classifiers-artifacts")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ import coursier.util.{ Config, Print }
|
|||
import org.apache.ivy.core.module.id.ModuleRevisionId
|
||||
|
||||
import sbt.{ UpdateReport, Classpaths, Resolver, Def }
|
||||
import sbt.Configurations.{ Compile, Test }
|
||||
import sbt.Keys._
|
||||
|
||||
import scala.collection.mutable
|
||||
|
|
@ -147,7 +146,7 @@ object Tasks {
|
|||
coursierProject.forAllProjects(state, projects).map(_.values.toVector)
|
||||
}
|
||||
|
||||
def coursierPublicationsTask: Def.Initialize[sbt.Task[Seq[(String, Publication)]]] =
|
||||
def coursierPublicationsTask(configsMap: (sbt.Configuration, String)*): Def.Initialize[sbt.Task[Seq[(String, Publication)]]] =
|
||||
(
|
||||
sbt.Keys.state,
|
||||
sbt.Keys.thisProjectRef,
|
||||
|
|
@ -158,17 +157,16 @@ object Tasks {
|
|||
).map { (state, projectRef, projId, sv, sbv, ivyConfs) =>
|
||||
|
||||
val packageTasks = Seq(packageBin, packageSrc, packageDoc)
|
||||
val configs = Seq(Compile, Test)
|
||||
|
||||
val sbtArtifacts =
|
||||
for {
|
||||
pkgTask <- packageTasks
|
||||
config <- configs
|
||||
(config, targetConfig) <- configsMap
|
||||
} yield {
|
||||
val publish = publishArtifact.in(projectRef).in(pkgTask).in(config).getOrElse(state, false)
|
||||
if (publish)
|
||||
Option(artifact.in(projectRef).in(pkgTask).in(config).getOrElse(state, null))
|
||||
.map(config.name -> _)
|
||||
.map(targetConfig -> _)
|
||||
else
|
||||
None
|
||||
}
|
||||
|
|
@ -219,7 +217,7 @@ object Tasks {
|
|||
sbtArtifactsPublication ++ extraSbtArtifactsPublication
|
||||
}
|
||||
|
||||
def coursierConfigurationsTask = Def.task {
|
||||
def coursierConfigurationsTask(shadedConfig: Option[(String, String)]) = Def.task {
|
||||
|
||||
val configs0 = ivyConfigurations.value.map { config =>
|
||||
config.name -> config.extendsConfigs.map(_.name)
|
||||
|
|
@ -238,10 +236,18 @@ object Tasks {
|
|||
helper(Set(c))
|
||||
}
|
||||
|
||||
configs0.map {
|
||||
val map = configs0.map {
|
||||
case (config, _) =>
|
||||
config -> allExtends(config)
|
||||
}
|
||||
|
||||
map ++ shadedConfig.toSeq.flatMap {
|
||||
case (baseConfig, shadedConfig) =>
|
||||
Seq(
|
||||
baseConfig -> (map.getOrElse(baseConfig, Set(baseConfig)) + shadedConfig),
|
||||
shadedConfig -> map.getOrElse(shadedConfig, Set(shadedConfig))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private case class ResolutionCacheKey(
|
||||
|
|
@ -647,14 +653,155 @@ object Tasks {
|
|||
}
|
||||
}
|
||||
|
||||
def updateTask(
|
||||
def artifactFilesOrErrors(
|
||||
withClassifiers: Boolean,
|
||||
sbtClassifiers: Boolean = false,
|
||||
ignoreArtifactErrors: Boolean = false
|
||||
) = Def.task {
|
||||
|
||||
def grouped[K, V](map: Seq[(K, V)]): Map[K, Seq[V]] =
|
||||
map.groupBy { case (k, _) => k }.map {
|
||||
// let's update only one module at once, for a better output
|
||||
// Downloads are already parallel, no need to parallelize further anyway
|
||||
synchronized {
|
||||
|
||||
lazy val cm = coursierSbtClassifiersModule.value
|
||||
|
||||
lazy val projectName = thisProjectRef.value.project
|
||||
|
||||
val parallelDownloads = coursierParallelDownloads.value
|
||||
val artifactsChecksums = coursierArtifactsChecksums.value
|
||||
val cachePolicies = coursierCachePolicies.value
|
||||
val ttl = coursierTtl.value
|
||||
val cache = coursierCache.value
|
||||
|
||||
val log = streams.value.log
|
||||
|
||||
val verbosityLevel = coursierVerbosity.value
|
||||
|
||||
val res = {
|
||||
if (withClassifiers && sbtClassifiers)
|
||||
coursierSbtClassifiersResolution
|
||||
else
|
||||
coursierResolution
|
||||
}.value
|
||||
|
||||
val classifiers =
|
||||
if (withClassifiers)
|
||||
Some {
|
||||
if (sbtClassifiers)
|
||||
cm.classifiers
|
||||
else
|
||||
transitiveClassifiers.value
|
||||
}
|
||||
else
|
||||
None
|
||||
|
||||
val allArtifacts =
|
||||
classifiers match {
|
||||
case None => res.artifacts
|
||||
case Some(cl) => res.classifiersArtifacts(cl)
|
||||
}
|
||||
|
||||
var pool: ExecutorService = null
|
||||
var artifactsLogger: TermDisplay = null
|
||||
|
||||
val printOptionalMessage = verbosityLevel >= 0 && verbosityLevel <= 1
|
||||
|
||||
val artifactFilesOrErrors = try {
|
||||
pool = Executors.newFixedThreadPool(parallelDownloads, Strategy.DefaultDaemonThreadFactory)
|
||||
artifactsLogger = createLogger()
|
||||
|
||||
val artifactFileOrErrorTasks = allArtifacts.toVector.map { a =>
|
||||
def f(p: CachePolicy) =
|
||||
Cache.file(
|
||||
a,
|
||||
cache,
|
||||
p,
|
||||
checksums = artifactsChecksums,
|
||||
logger = Some(artifactsLogger),
|
||||
pool = pool,
|
||||
ttl = ttl
|
||||
)
|
||||
|
||||
cachePolicies.tail
|
||||
.foldLeft(f(cachePolicies.head))(_ orElse f(_))
|
||||
.run
|
||||
.map((a, _))
|
||||
}
|
||||
|
||||
val artifactInitialMessage =
|
||||
if (verbosityLevel >= 0)
|
||||
s"Fetching artifacts of $projectName" +
|
||||
(if (sbtClassifiers) " (sbt classifiers)" else "")
|
||||
else
|
||||
""
|
||||
|
||||
if (verbosityLevel >= 2)
|
||||
log.info(artifactInitialMessage)
|
||||
|
||||
artifactsLogger.init(if (printOptionalMessage) log.info(artifactInitialMessage))
|
||||
|
||||
Task.gatherUnordered(artifactFileOrErrorTasks).attemptRun match {
|
||||
case -\/(ex) =>
|
||||
ResolutionError.UnknownDownloadException(ex)
|
||||
.throwException()
|
||||
case \/-(l) =>
|
||||
l.toMap
|
||||
}
|
||||
} finally {
|
||||
if (pool != null)
|
||||
pool.shutdown()
|
||||
if (artifactsLogger != null)
|
||||
if ((artifactsLogger.stopDidPrintSomething() && printOptionalMessage) || verbosityLevel >= 2)
|
||||
log.info(
|
||||
s"Fetched artifacts of $projectName" +
|
||||
(if (sbtClassifiers) " (sbt classifiers)" else "")
|
||||
)
|
||||
}
|
||||
|
||||
artifactFilesOrErrors
|
||||
}
|
||||
}
|
||||
|
||||
private def artifactFileOpt(
|
||||
sbtBootJarOverrides: Map[(Module, String), File],
|
||||
artifactFiles: Map[Artifact, File],
|
||||
erroredArtifacts: Set[Artifact],
|
||||
log: sbt.Logger,
|
||||
module: Module,
|
||||
version: String,
|
||||
artifact: Artifact
|
||||
) = {
|
||||
|
||||
val artifact0 = artifact
|
||||
.copy(attributes = Attributes()) // temporary hack :-(
|
||||
|
||||
// Under some conditions, SBT puts the scala JARs of its own classpath
|
||||
// in the application classpath. Ensuring we return SBT's jars rather than
|
||||
// JARs from the coursier cache, so that a same JAR doesn't land twice in the
|
||||
// application classpath (once via SBT jars, once via coursier cache).
|
||||
val fromBootJars =
|
||||
if (artifact.classifier.isEmpty && artifact.`type` == "jar")
|
||||
sbtBootJarOverrides.get((module, version))
|
||||
else
|
||||
None
|
||||
|
||||
val res = fromBootJars.orElse(artifactFiles.get(artifact0))
|
||||
|
||||
if (res.isEmpty && !erroredArtifacts(artifact0))
|
||||
log.error(s"${artifact.url} not downloaded (should not happen)")
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
def updateTask(
|
||||
shadedConfigOpt: Option[(String, String)],
|
||||
withClassifiers: Boolean,
|
||||
sbtClassifiers: Boolean = false,
|
||||
ignoreArtifactErrors: Boolean = false
|
||||
) = Def.task {
|
||||
|
||||
def grouped[K, V](map: Seq[(K, V)])(mapKey: K => K): Map[K, Seq[V]] =
|
||||
map.groupBy { case (k, _) => mapKey(k) }.map {
|
||||
case (k, l) =>
|
||||
k -> l.map { case (_, v) => v }
|
||||
}
|
||||
|
|
@ -677,8 +824,6 @@ object Tasks {
|
|||
|
||||
lazy val cm = coursierSbtClassifiersModule.value
|
||||
|
||||
lazy val projectName = thisProjectRef.value.project
|
||||
|
||||
val currentProject =
|
||||
if (sbtClassifiers) {
|
||||
val sv = scalaVersion.value
|
||||
|
|
@ -699,46 +844,10 @@ object Tasks {
|
|||
proj.copy(publications = publications)
|
||||
}
|
||||
|
||||
val ivySbt0 = ivySbt.value
|
||||
val ivyCacheManager = ivySbt0.withIvy(streams.value.log)(ivy =>
|
||||
ivy.getResolutionCacheManager
|
||||
)
|
||||
|
||||
val ivyModule = ModuleRevisionId.newInstance(
|
||||
currentProject.module.organization,
|
||||
currentProject.module.name,
|
||||
currentProject.version,
|
||||
currentProject.module.attributes.asJava
|
||||
)
|
||||
val cacheIvyFile = ivyCacheManager.getResolvedIvyFileInCache(ivyModule)
|
||||
val cacheIvyPropertiesFile = ivyCacheManager.getResolvedIvyPropertiesInCache(ivyModule)
|
||||
|
||||
val parallelDownloads = coursierParallelDownloads.value
|
||||
val artifactsChecksums = coursierArtifactsChecksums.value
|
||||
val cachePolicies = coursierCachePolicies.value
|
||||
val ttl = coursierTtl.value
|
||||
val cache = coursierCache.value
|
||||
|
||||
val log = streams.value.log
|
||||
|
||||
val verbosityLevel = coursierVerbosity.value
|
||||
|
||||
// required for publish to be fine, later on
|
||||
def writeIvyFiles() = {
|
||||
val printer = new scala.xml.PrettyPrinter(80, 2)
|
||||
|
||||
val b = new StringBuilder
|
||||
b ++= """<?xml version="1.0" encoding="UTF-8"?>"""
|
||||
b += '\n'
|
||||
b ++= printer.format(MakeIvyXml(currentProject))
|
||||
cacheIvyFile.getParentFile.mkdirs()
|
||||
FileUtil.write(cacheIvyFile, b.result().getBytes("UTF-8"))
|
||||
|
||||
// Just writing an empty file here... Are these only used?
|
||||
cacheIvyPropertiesFile.getParentFile.mkdirs()
|
||||
FileUtil.write(cacheIvyPropertiesFile, "".getBytes("UTF-8"))
|
||||
}
|
||||
|
||||
val res = {
|
||||
if (withClassifiers && sbtClassifiers)
|
||||
coursierSbtClassifiersResolution
|
||||
|
|
@ -748,9 +857,25 @@ object Tasks {
|
|||
|
||||
def report = {
|
||||
|
||||
val depsByConfig = grouped(currentProject.dependencies)
|
||||
val depsByConfig = grouped(currentProject.dependencies)(
|
||||
config =>
|
||||
shadedConfigOpt match {
|
||||
case Some((baseConfig, `config`)) =>
|
||||
baseConfig
|
||||
case _ =>
|
||||
config
|
||||
}
|
||||
)
|
||||
|
||||
val configs = coursierConfigurations.value
|
||||
val configs = {
|
||||
val m = coursierConfigurations.value
|
||||
shadedConfigOpt.fold(m) {
|
||||
case (baseConfig, shadedConfig) =>
|
||||
(m - shadedConfig) + (
|
||||
baseConfig -> (m.getOrElse(baseConfig, Set()) - shadedConfig)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (verbosityLevel >= 2) {
|
||||
val finalDeps = Config.dependenciesWithConfig(
|
||||
|
|
@ -775,75 +900,22 @@ object Tasks {
|
|||
else
|
||||
None
|
||||
|
||||
val allArtifacts =
|
||||
classifiers match {
|
||||
case None => res.artifacts
|
||||
case Some(cl) => res.classifiersArtifacts(cl)
|
||||
}
|
||||
|
||||
var pool: ExecutorService = null
|
||||
var artifactsLogger: TermDisplay = null
|
||||
|
||||
val printOptionalMessage = verbosityLevel >= 0 && verbosityLevel <= 1
|
||||
|
||||
val artifactFilesOrErrors = try {
|
||||
pool = Executors.newFixedThreadPool(parallelDownloads, Strategy.DefaultDaemonThreadFactory)
|
||||
artifactsLogger = createLogger()
|
||||
|
||||
val artifactFileOrErrorTasks = allArtifacts.toVector.map { a =>
|
||||
def f(p: CachePolicy) =
|
||||
Cache.file(
|
||||
a,
|
||||
cache,
|
||||
p,
|
||||
checksums = artifactsChecksums,
|
||||
logger = Some(artifactsLogger),
|
||||
pool = pool,
|
||||
ttl = ttl
|
||||
)
|
||||
|
||||
cachePolicies.tail
|
||||
.foldLeft(f(cachePolicies.head))(_ orElse f(_))
|
||||
.run
|
||||
.map((a, _))
|
||||
}
|
||||
|
||||
val artifactInitialMessage =
|
||||
if (verbosityLevel >= 0)
|
||||
s"Fetching artifacts of $projectName" +
|
||||
(if (sbtClassifiers) " (sbt classifiers)" else "")
|
||||
val artifactFilesOrErrors0 = (
|
||||
if (withClassifiers) {
|
||||
if (sbtClassifiers)
|
||||
Keys.coursierSbtClassifiersArtifacts
|
||||
else
|
||||
""
|
||||
Keys.coursierClassifiersArtifacts
|
||||
} else
|
||||
Keys.coursierArtifacts
|
||||
).value
|
||||
|
||||
if (verbosityLevel >= 2)
|
||||
log.info(artifactInitialMessage)
|
||||
|
||||
artifactsLogger.init(if (printOptionalMessage) log.info(artifactInitialMessage))
|
||||
|
||||
Task.gatherUnordered(artifactFileOrErrorTasks).attemptRun match {
|
||||
case -\/(ex) =>
|
||||
ResolutionError.UnknownDownloadException(ex)
|
||||
.throwException()
|
||||
case \/-(l) =>
|
||||
l.toMap
|
||||
}
|
||||
} finally {
|
||||
if (pool != null)
|
||||
pool.shutdown()
|
||||
if (artifactsLogger != null)
|
||||
if ((artifactsLogger.stopDidPrintSomething() && printOptionalMessage) || verbosityLevel >= 2)
|
||||
log.info(
|
||||
s"Fetched artifacts of $projectName" +
|
||||
(if (sbtClassifiers) " (sbt classifiers)" else "")
|
||||
)
|
||||
}
|
||||
|
||||
val artifactFiles = artifactFilesOrErrors.collect {
|
||||
val artifactFiles = artifactFilesOrErrors0.collect {
|
||||
case (artifact, \/-(file)) =>
|
||||
artifact -> file
|
||||
}
|
||||
|
||||
val artifactErrors = artifactFilesOrErrors.toVector.collect {
|
||||
val artifactErrors = artifactFilesOrErrors0.toVector.collect {
|
||||
case (_, -\/(err)) =>
|
||||
err
|
||||
}
|
||||
|
|
@ -858,42 +930,25 @@ object Tasks {
|
|||
}
|
||||
|
||||
// can be non empty only if ignoreArtifactErrors is true
|
||||
val erroredArtifacts = artifactFilesOrErrors.collect {
|
||||
val erroredArtifacts = artifactFilesOrErrors0.collect {
|
||||
case (artifact, -\/(_)) =>
|
||||
artifact
|
||||
}.toSet
|
||||
|
||||
def artifactFileOpt(module: Module, version: String, artifact: Artifact) = {
|
||||
|
||||
val artifact0 = artifact
|
||||
.copy(attributes = Attributes()) // temporary hack :-(
|
||||
|
||||
// Under some conditions, SBT puts the scala JARs of its own classpath
|
||||
// in the application classpath. Ensuring we return SBT's jars rather than
|
||||
// JARs from the coursier cache, so that a same JAR doesn't land twice in the
|
||||
// application classpath (once via SBT jars, once via coursier cache).
|
||||
val fromBootJars =
|
||||
if (artifact.classifier.isEmpty && artifact.`type` == "jar")
|
||||
sbtBootJarOverrides.get((module, version))
|
||||
else
|
||||
None
|
||||
|
||||
val res = fromBootJars.orElse(artifactFiles.get(artifact0))
|
||||
|
||||
if (res.isEmpty && !erroredArtifacts(artifact0))
|
||||
log.error(s"${artifact.url} not downloaded (should not happen)")
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
writeIvyFiles()
|
||||
|
||||
ToSbt.updateReport(
|
||||
depsByConfig,
|
||||
res,
|
||||
configs,
|
||||
classifiers,
|
||||
artifactFileOpt
|
||||
artifactFileOpt(
|
||||
sbtBootJarOverrides,
|
||||
artifactFiles,
|
||||
erroredArtifacts,
|
||||
log,
|
||||
_,
|
||||
_,
|
||||
_
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
$ delete output
|
||||
> run
|
||||
$ exists output
|
||||
$ delete shapeless_2.11-2.3.0.jar
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
addSbtPlugin("org.xerial.sbt" % "sbt-pack" % "0.8.0")
|
||||
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.13")
|
||||
addSbtPlugin("org.xerial.sbt" % "sbt-pack" % "0.8.2")
|
||||
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.14")
|
||||
addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.0.0")
|
||||
addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.4.0")
|
||||
addSbtPlugin("org.tpolecat" % "tut-plugin" % "0.4.6")
|
||||
addSbtPlugin("io.get-coursier" % "sbt-coursier" % "1.0.0-M14")
|
||||
addSbtPlugin("org.tpolecat" % "tut-plugin" % "0.4.8")
|
||||
addSbtPlugin("io.get-coursier" % "sbt-coursier" % "1.0.0-M15-1")
|
||||
addSbtPlugin("com.typesafe.sbt" % "sbt-proguard" % "0.2.2")
|
||||
addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.1.11")
|
||||
addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.1.13")
|
||||
libraryDependencies += "org.scala-sbt" % "scripted-plugin" % sbtVersion.value
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
addSbtPlugin("io.get-coursier" % "sbt-coursier" % "1.0.0-M14")
|
||||
addSbtPlugin("io.get-coursier" % "sbt-coursier" % "1.0.0-M15-1")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,152 @@
|
|||
package coursier
|
||||
|
||||
import java.io.{File, FileInputStream}
|
||||
import java.util.jar.JarInputStream
|
||||
import java.util.zip.{ZipEntry, ZipInputStream}
|
||||
|
||||
import com.tonicsystems.jarjar.classpath.ClassPath
|
||||
import com.tonicsystems.jarjar.transform.JarTransformer
|
||||
import com.tonicsystems.jarjar.transform.config.ClassRename
|
||||
import com.tonicsystems.jarjar.transform.jar.DefaultJarProcessor
|
||||
import coursier.core.Orders
|
||||
import sbt.file
|
||||
|
||||
import scalaz.{\/, \/-}
|
||||
|
||||
object Shading {
|
||||
|
||||
// FIXME Also vaguely in cli
|
||||
def zipEntries(zipStream: ZipInputStream): Iterator[ZipEntry] =
|
||||
new Iterator[ZipEntry] {
|
||||
var nextEntry = Option.empty[ZipEntry]
|
||||
def update() =
|
||||
nextEntry = Option(zipStream.getNextEntry)
|
||||
|
||||
update()
|
||||
|
||||
def hasNext = nextEntry.nonEmpty
|
||||
def next() = {
|
||||
val ent = nextEntry.get
|
||||
update()
|
||||
ent
|
||||
}
|
||||
}
|
||||
|
||||
def jarClassNames(jar: File): Seq[String] = {
|
||||
|
||||
var fis: FileInputStream = null
|
||||
var zis: JarInputStream = null
|
||||
|
||||
try {
|
||||
fis = new FileInputStream(jar)
|
||||
zis = new JarInputStream(fis)
|
||||
|
||||
zipEntries(zis)
|
||||
.map(_.getName)
|
||||
.filter(_.endsWith(".class"))
|
||||
.map(_.stripSuffix(".class").replace('/', '.'))
|
||||
.toVector
|
||||
} finally {
|
||||
if (zis != null)
|
||||
zis.close()
|
||||
if (fis != null)
|
||||
fis.close()
|
||||
}
|
||||
}
|
||||
|
||||
def createPackage(
|
||||
baseJar: File,
|
||||
currentProject: Project,
|
||||
res: Resolution,
|
||||
configs: Map[String, Set[String]],
|
||||
artifactFilesOrErrors: Map[Artifact, FileError \/ File],
|
||||
shadingNamespace: String,
|
||||
baseConfig: String,
|
||||
shadedConf: String,
|
||||
log: sbt.Logger
|
||||
) = {
|
||||
|
||||
val outputJar = new File(
|
||||
baseJar.getParentFile,
|
||||
baseJar.getName.stripSuffix(".jar") + "-shading.jar"
|
||||
)
|
||||
|
||||
def configDependencies(config: String) = {
|
||||
|
||||
def minDependencies(dependencies: Set[Dependency]): Set[Dependency] =
|
||||
Orders.minDependencies(
|
||||
dependencies,
|
||||
dep =>
|
||||
res
|
||||
.projectCache
|
||||
.get(dep)
|
||||
.map(_._2.configurations)
|
||||
.getOrElse(Map.empty)
|
||||
)
|
||||
|
||||
val includedConfigs = configs.getOrElse(config, Set.empty) + config
|
||||
|
||||
minDependencies(
|
||||
currentProject
|
||||
.dependencies
|
||||
.collect {
|
||||
case (cfg, dep) if includedConfigs(cfg) =>
|
||||
dep
|
||||
}
|
||||
.toSet
|
||||
)
|
||||
}
|
||||
|
||||
val dependencyArtifacts = res.dependencyArtifacts.toMap
|
||||
|
||||
val artifactFilesOrErrors0 = artifactFilesOrErrors
|
||||
.collect {
|
||||
case (a, \/-(f)) => a.url -> f
|
||||
}
|
||||
|
||||
val compileDeps = configDependencies(baseConfig)
|
||||
val shadedDeps = configDependencies(shadedConf)
|
||||
|
||||
val compileOnlyDeps = compileDeps.filterNot(shadedDeps)
|
||||
|
||||
log.info(s"Found ${compileDeps.size} dependencies in $baseConfig")
|
||||
log.debug(compileDeps.toVector.map(" " + _).sorted.mkString("\n"))
|
||||
log.info(s"Found ${compileOnlyDeps.size} dependencies only in $baseConfig")
|
||||
log.debug(compileOnlyDeps.toVector.map(" " + _).sorted.mkString("\n"))
|
||||
log.info(s"Found ${shadedDeps.size} dependencies in $shadedConf")
|
||||
log.debug(shadedDeps.toVector.map(" " + _).sorted.mkString("\n"))
|
||||
|
||||
def files(deps: Set[Dependency]) = res
|
||||
.subset(deps)
|
||||
.dependencies
|
||||
.toSeq
|
||||
.flatMap(dependencyArtifacts.get)
|
||||
.map(_.url)
|
||||
.flatMap(artifactFilesOrErrors0.get)
|
||||
|
||||
val compileOnlyJars = files(compileOnlyDeps)
|
||||
val shadedJars = files(shadedDeps)
|
||||
|
||||
log.info(s"Found ${compileOnlyJars.length} JAR(s) only in $baseConfig")
|
||||
log.debug(compileOnlyJars.map(" " + _).sorted.mkString("\n"))
|
||||
log.info(s"Found ${shadedJars.length} JAR(s) in $shadedConf")
|
||||
log.debug(shadedJars.map(" " + _).sorted.mkString("\n"))
|
||||
|
||||
val shadeJars = shadedJars.filterNot(compileOnlyJars.toSet)
|
||||
val shadeClasses = shadeJars.flatMap(Shading.jarClassNames)
|
||||
|
||||
log.info(s"Will shade ${shadeClasses.length} class(es)")
|
||||
log.debug(shadeClasses.map(" " + _).sorted.mkString("\n"))
|
||||
|
||||
val processor = new DefaultJarProcessor
|
||||
for (cls <- shadeClasses)
|
||||
processor.addClassRename(new ClassRename(cls, shadingNamespace + ".@0"))
|
||||
|
||||
val transformer = new JarTransformer(outputJar, processor)
|
||||
val cp = new ClassPath(file(sys.props("user.dir")), (baseJar +: shadeJars).toArray)
|
||||
transformer.transform(cp)
|
||||
|
||||
outputJar
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
package coursier
|
||||
|
||||
import coursier.ivy.IvyXml.{ mappings => ivyXmlMappings }
|
||||
import sbt.Keys._
|
||||
import sbt.{AutoPlugin, Compile, Configuration, TaskKey, inConfig}
|
||||
|
||||
object ShadingPlugin extends AutoPlugin {
|
||||
|
||||
override def trigger = noTrigger
|
||||
|
||||
override def requires = sbt.plugins.IvyPlugin
|
||||
|
||||
private val baseSbtConfiguration = Compile
|
||||
val Shading = Configuration("shading", "", isPublic = false, List(baseSbtConfiguration), transitive = true)
|
||||
|
||||
private val baseDependencyConfiguration = "compile"
|
||||
val Shaded = Configuration("shaded", "", isPublic = true, List(), transitive = true)
|
||||
|
||||
val shadingNamespace = TaskKey[String]("shading-namespace")
|
||||
|
||||
object autoImport {
|
||||
|
||||
/** Scope for shading related tasks */
|
||||
val Shading = ShadingPlugin.Shading
|
||||
|
||||
/** Ivy configuration for shaded dependencies */
|
||||
val Shaded = ShadingPlugin.Shaded
|
||||
|
||||
val shadingNamespace = ShadingPlugin.shadingNamespace
|
||||
}
|
||||
|
||||
// same as similar things under sbt.Classpaths, tweaking a bit the configuration scope
|
||||
lazy val shadingDefaultArtifactTasks =
|
||||
makePom +: Seq(packageBin, packageSrc, packageDoc).map(_.in(Shading))
|
||||
lazy val shadingJvmPublishSettings = Seq(
|
||||
artifacts <<= sbt.Classpaths.artifactDefs(shadingDefaultArtifactTasks),
|
||||
packagedArtifacts <<= sbt.Classpaths.packaged(shadingDefaultArtifactTasks)
|
||||
)
|
||||
|
||||
import CoursierPlugin.autoImport._
|
||||
|
||||
override lazy val projectSettings =
|
||||
Seq(
|
||||
coursierConfigurations <<= Tasks.coursierConfigurationsTask(
|
||||
Some(baseDependencyConfiguration -> Shaded.name)
|
||||
),
|
||||
ivyConfigurations := Shaded +: ivyConfigurations.value.map {
|
||||
conf =>
|
||||
if (conf.name == "compile")
|
||||
conf.extend(Shaded)
|
||||
else
|
||||
conf
|
||||
}
|
||||
) ++
|
||||
inConfig(Shading)(
|
||||
sbt.Defaults.configSettings ++
|
||||
sbt.Classpaths.ivyBaseSettings ++
|
||||
sbt.Classpaths.ivyPublishSettings ++
|
||||
shadingJvmPublishSettings ++
|
||||
CoursierPlugin.coursierSettings(
|
||||
Some(baseDependencyConfiguration -> Shaded.name),
|
||||
Seq(Shading -> Compile.name)
|
||||
) ++
|
||||
CoursierPlugin.treeSettings ++
|
||||
Seq(
|
||||
configuration := baseSbtConfiguration, // wuw
|
||||
ivyConfigurations := ivyConfigurations.in(baseSbtConfiguration).value
|
||||
.filter(_.name != Shaded.name)
|
||||
.map(c => c.copy(extendsConfigs = c.extendsConfigs.filter(_.name != Shaded.name))),
|
||||
libraryDependencies := libraryDependencies.in(baseSbtConfiguration).value.filter { dep =>
|
||||
val isShaded = dep.configurations.exists { mappings =>
|
||||
ivyXmlMappings(mappings).exists(_._1 == Shaded.name)
|
||||
}
|
||||
|
||||
!isShaded
|
||||
},
|
||||
// required for cross-projects in particular
|
||||
unmanagedSourceDirectories := (unmanagedSourceDirectories in Compile).value,
|
||||
packageBin := {
|
||||
coursier.Shading.createPackage(
|
||||
packageBin.in(baseSbtConfiguration).value,
|
||||
coursierProject.in(baseSbtConfiguration).value,
|
||||
coursierResolution.in(baseSbtConfiguration).value,
|
||||
coursierConfigurations.in(baseSbtConfiguration).value,
|
||||
Keys.coursierArtifacts.in(baseSbtConfiguration).value,
|
||||
shadingNamespace.?.value.getOrElse {
|
||||
throw new NoSuchElementException("shadingNamespace key not set")
|
||||
},
|
||||
baseDependencyConfiguration,
|
||||
Shaded.name,
|
||||
streams.value.log
|
||||
)
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
lazy val root = crossProject
|
||||
.in(file("."))
|
||||
.jvmConfigure(
|
||||
_.enablePlugins(coursier.ShadingPlugin)
|
||||
)
|
||||
.jvmSettings(
|
||||
shadingNamespace := "test.shaded",
|
||||
libraryDependencies += "io.argonaut" %% "argonaut" % "6.2-RC2" % "shaded"
|
||||
)
|
||||
.settings(
|
||||
scalaVersion := "2.11.8",
|
||||
organization := "io.get-coursier.test",
|
||||
name := "shading-cross-test",
|
||||
version := "0.1.0-SNAPSHOT",
|
||||
libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value
|
||||
)
|
||||
|
||||
lazy val jvm = root.jvm
|
||||
lazy val js = root.js
|
||||
Binary file not shown.
|
|
@ -0,0 +1,21 @@
|
|||
import java.io.File
|
||||
import java.nio.file.Files
|
||||
|
||||
import argonaut._
|
||||
|
||||
import Foo._
|
||||
|
||||
object Main extends App {
|
||||
|
||||
val expectedClassName0 = expectedClassName(args.headOption == Some("--shaded"))
|
||||
|
||||
Console.err.println(s"Expected class name: $expectedClassName0")
|
||||
Console.err.println(s"Class name: $className")
|
||||
|
||||
if (className != expectedClassName0)
|
||||
sys.error(s"Expected class name $expectedClassName0, got $className")
|
||||
|
||||
val msg = Json.obj().nospaces
|
||||
|
||||
Files.write(new File("output").toPath, msg.getBytes("UTF-8"))
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
val pluginVersion = sys.props.getOrElse(
|
||||
"plugin.version",
|
||||
throw new RuntimeException(
|
||||
"""|The system property 'plugin.version' is not defined.
|
||||
|Specify this property using the scriptedLaunchOpts -D.""".stripMargin
|
||||
)
|
||||
)
|
||||
|
||||
addSbtPlugin("io.get-coursier" % "sbt-shading" % pluginVersion)
|
||||
}
|
||||
|
||||
// for the locally publish jarjar
|
||||
resolvers += Resolver.mavenLocal
|
||||
|
||||
val coursierJarjarVersion = "1.0.1-coursier-SNAPSHOT"
|
||||
|
||||
def coursierJarjarFoundInM2 =
|
||||
(file(sys.props("user.home")) / s".m2/repository/org/anarres/jarjar/jarjar-core/$coursierJarjarVersion").exists()
|
||||
|
||||
def jarjarVersion =
|
||||
if (coursierJarjarFoundInM2)
|
||||
coursierJarjarVersion
|
||||
else
|
||||
sys.error(
|
||||
"Ad hoc jarjar version not found. Run\n" +
|
||||
" git clone https://github.com/alexarchambault/jarjar.git && cd jarjar && git checkout 249c8dbb970f8 && ./gradlew install\n" +
|
||||
"to run this test"
|
||||
)
|
||||
|
||||
libraryDependencies += "org.anarres.jarjar" % "jarjar-core" % jarjarVersion
|
||||
|
||||
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.13")
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
|
||||
import argonaut._
|
||||
|
||||
object Foo {
|
||||
|
||||
def expectedClassName(shaded: Boolean) =
|
||||
if (shaded)
|
||||
"test.shaded.argonaut.Json"
|
||||
else
|
||||
// Don't use the literal "argonaut.Json", that seems to get
|
||||
// changed to "test.shaded.argonaut.Json" by shading
|
||||
"argonaut" + '.' + "Json"
|
||||
|
||||
val className = classOf[Json].getName
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
$ delete output
|
||||
> rootJVM/run
|
||||
$ exists output
|
||||
$ delete output
|
||||
> rootJVM/publishLocal
|
||||
$ exec java -jar coursier launch io.get-coursier.test:shading-cross-test_2.11:0.1.0-SNAPSHOT
|
||||
-$ exec java -jar coursier launch io.get-coursier.test:shading-cross-test_2.11:0.1.0-SNAPSHOT -- --shaded
|
||||
> rootJVM/shading:publishLocal
|
||||
-$ exec java -jar coursier launch io.get-coursier.test:shading-cross-test_2.11:0.1.0-SNAPSHOT
|
||||
$ exec java -jar coursier launch io.get-coursier.test:shading-cross-test_2.11:0.1.0-SNAPSHOT -- --shaded
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
enablePlugins(coursier.ShadingPlugin)
|
||||
shadingNamespace := "test.shaded"
|
||||
|
||||
libraryDependencies += "io.argonaut" %% "argonaut" % "6.2-RC2" % "shaded"
|
||||
|
||||
scalaVersion := "2.11.8"
|
||||
organization := "io.get-coursier.test"
|
||||
name := "shading-base-test"
|
||||
version := "0.1.0-SNAPSHOT"
|
||||
Binary file not shown.
|
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
val pluginVersion = sys.props.getOrElse(
|
||||
"plugin.version",
|
||||
throw new RuntimeException(
|
||||
"""|The system property 'plugin.version' is not defined.
|
||||
|Specify this property using the scriptedLaunchOpts -D.""".stripMargin
|
||||
)
|
||||
)
|
||||
|
||||
addSbtPlugin("io.get-coursier" % "sbt-shading" % pluginVersion)
|
||||
}
|
||||
|
||||
// for the locally publish jarjar
|
||||
resolvers += Resolver.mavenLocal
|
||||
|
||||
val coursierJarjarVersion = "1.0.1-coursier-SNAPSHOT"
|
||||
|
||||
def coursierJarjarFoundInM2 =
|
||||
(file(sys.props("user.home")) / s".m2/repository/org/anarres/jarjar/jarjar-core/$coursierJarjarVersion").exists()
|
||||
|
||||
def jarjarVersion =
|
||||
if (coursierJarjarFoundInM2)
|
||||
coursierJarjarVersion
|
||||
else
|
||||
sys.error(
|
||||
"Ad hoc jarjar version not found. Run\n" +
|
||||
" git clone https://github.com/alexarchambault/jarjar.git && cd jarjar && git checkout 249c8dbb970f8 && ./gradlew install\n" +
|
||||
"to run this test"
|
||||
)
|
||||
|
||||
libraryDependencies += "org.anarres.jarjar" % "jarjar-core" % jarjarVersion
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
import java.io.File
|
||||
import java.nio.file.Files
|
||||
|
||||
import argonaut._
|
||||
|
||||
object Main extends App {
|
||||
|
||||
val expectedClassName =
|
||||
if (args.headOption == Some("--shaded"))
|
||||
"test.shaded.argonaut.Json"
|
||||
else
|
||||
// Don't use the literal "argonaut.Json", that seems to get
|
||||
// changed to "test.shaded.argonaut.Json" by shading
|
||||
"argonaut" + '.' + "Json"
|
||||
|
||||
val className = classOf[Json].getName
|
||||
|
||||
Console.err.println(s"Expected class name: $expectedClassName")
|
||||
Console.err.println(s"Class name: $className")
|
||||
|
||||
if (className != expectedClassName)
|
||||
sys.error(s"Expected class name $expectedClassName, got $className")
|
||||
|
||||
val msg = Json.obj().nospaces
|
||||
|
||||
Files.write(new File("output").toPath, msg.getBytes("UTF-8"))
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
$ delete output
|
||||
> run
|
||||
$ exists output
|
||||
> publishLocal
|
||||
$ exec java -jar coursier launch io.get-coursier.test:shading-base-test_2.11:0.1.0-SNAPSHOT
|
||||
-$ exec java -jar coursier launch io.get-coursier.test:shading-base-test_2.11:0.1.0-SNAPSHOT -- --shaded
|
||||
> shading:publishLocal
|
||||
-$ exec java -jar coursier launch io.get-coursier.test:shading-base-test_2.11:0.1.0-SNAPSHOT
|
||||
$ exec java -jar coursier launch io.get-coursier.test:shading-base-test_2.11:0.1.0-SNAPSHOT -- --shaded
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
enablePlugins(coursier.ShadingPlugin)
|
||||
shadingNamespace := "test.shaded"
|
||||
|
||||
libraryDependencies ++= Seq(
|
||||
"com.github.alexarchambault" %% "argonaut-shapeless_6.2" % "1.2.0-M4" % "shaded",
|
||||
"com.chuusai" %% "shapeless" % "2.3.2",
|
||||
"org.scala-lang" % "scala-reflect" % scalaVersion.value
|
||||
)
|
||||
|
||||
scalaVersion := "2.11.8"
|
||||
organization := "io.get-coursier.test"
|
||||
name := "shading-transitive-test"
|
||||
version := "0.1.0-SNAPSHOT"
|
||||
Binary file not shown.
|
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
val pluginVersion = sys.props.getOrElse(
|
||||
"plugin.version",
|
||||
throw new RuntimeException(
|
||||
"""|The system property 'plugin.version' is not defined.
|
||||
|Specify this property using the scriptedLaunchOpts -D.""".stripMargin
|
||||
)
|
||||
)
|
||||
|
||||
addSbtPlugin("io.get-coursier" % "sbt-shading" % pluginVersion)
|
||||
}
|
||||
|
||||
// for the locally publish jarjar
|
||||
resolvers += Resolver.mavenLocal
|
||||
|
||||
val coursierJarjarVersion = "1.0.1-coursier-SNAPSHOT"
|
||||
|
||||
def coursierJarjarFoundInM2 =
|
||||
(file(sys.props("user.home")) / s".m2/repository/org/anarres/jarjar/jarjar-core/$coursierJarjarVersion").exists()
|
||||
|
||||
def jarjarVersion =
|
||||
if (coursierJarjarFoundInM2)
|
||||
coursierJarjarVersion
|
||||
else
|
||||
sys.error(
|
||||
"Ad hoc jarjar version not found. Run\n" +
|
||||
" git clone https://github.com/alexarchambault/jarjar.git && cd jarjar && git checkout 249c8dbb970f8 && ./gradlew install\n" +
|
||||
"to run this test"
|
||||
)
|
||||
|
||||
libraryDependencies += "org.anarres.jarjar" % "jarjar-core" % jarjarVersion
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
import java.io.File
|
||||
import java.nio.file.Files
|
||||
|
||||
import argonaut._
|
||||
|
||||
object Main extends App {
|
||||
|
||||
val expectedClassName =
|
||||
if (args.headOption == Some("--shaded"))
|
||||
"test.shaded.argonaut.Json"
|
||||
else
|
||||
// Don't use the literal "argonaut.Json", that seems to get
|
||||
// changed to "test.shaded.argonaut.Json" by shading
|
||||
"argonaut" + '.' + "Json"
|
||||
|
||||
val className = classOf[Json].getName
|
||||
|
||||
Console.err.println(s"Expected class name: $expectedClassName")
|
||||
Console.err.println(s"Class name: $className")
|
||||
|
||||
if (className != expectedClassName)
|
||||
sys.error(s"Expected class name $expectedClassName, got $className")
|
||||
|
||||
val msg = Json.obj().nospaces
|
||||
|
||||
Files.write(new File("output").toPath, msg.getBytes("UTF-8"))
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
$ delete output
|
||||
> run
|
||||
$ exists output
|
||||
> publishLocal
|
||||
$ exec java -jar coursier launch io.get-coursier.test:shading-transitive-test_2.11:0.1.0-SNAPSHOT
|
||||
-$ exec java -jar coursier launch io.get-coursier.test:shading-transitive-test_2.11:0.1.0-SNAPSHOT -- --shaded
|
||||
> shading:publishLocal
|
||||
-$ exec java -jar coursier launch io.get-coursier.test:shading-transitive-test_2.11:0.1.0-SNAPSHOT
|
||||
$ exec java -jar coursier launch io.get-coursier.test:shading-transitive-test_2.11:0.1.0-SNAPSHOT -- --shaded
|
||||
|
|
@ -2,7 +2,7 @@ com.lihaoyi:fastparse-utils_2.11:0.4.2:default
|
|||
com.lihaoyi:fastparse_2.11:0.4.2:default
|
||||
com.lihaoyi:sourcecode_2.11:0.1.3:default
|
||||
io.get-coursier:coursier_2.11:1.0.0-SNAPSHOT:compile
|
||||
org.jsoup:jsoup:1.9.2:default
|
||||
org.jsoup:jsoup:1.10.2:default
|
||||
org.scala-lang:scala-library:2.11.8:default
|
||||
org.scala-lang.modules:scala-xml_2.11:1.0.5:default
|
||||
org.scalaz:scalaz-core_2.11:7.2.7:default
|
||||
org.scala-lang.modules:scala-xml_2.11:1.0.6:default
|
||||
org.scalaz:scalaz-core_2.11:7.2.8:default
|
||||
|
|
|
|||
Loading…
Reference in New Issue