diff --git a/build.sbt b/build.sbt index c0f3165ea..677b3925b 100644 --- a/build.sbt +++ b/build.sbt @@ -1,136 +1,34 @@ -import java.io.FileOutputStream -import com.typesafe.sbt.pgp.PgpSettings -val binaryCompatibilityVersion = "1.0.0-M14" -val binaryCompatibility212Version = "1.0.0-M15" +import Aliases._ +import CoursierSettings._ +import Publish._ -parallelExecution in Global := false - -lazy val IntegrationTest = config("it") extend Test - -lazy val scalazVersion = "7.2.8" +parallelExecution.in(Global) := false lazy val core = crossProject - .settings(commonSettings) - .settings(mimaPreviousArtifactSettings) - .jvmConfigure(_ - .enablePlugins(_root_.coursier.ShadingPlugin) - ) + .jvmConfigure(_.enablePlugins(ShadingPlugin)) .jvmSettings( - libraryDependencies ++= { - - val extra = - if (scalaBinaryVersion.value == "2.10") - // directly depending on that one so that it doesn't get shaded - Seq("org.scalamacros" %% "quasiquotes" % "2.1.0") - else - Nil - - Seq("com.lihaoyi" %% "fastparse" % "0.4.2" % "shaded") ++ extra - }, - shadingSettings + shading, + quasiQuotesIfNecessary, + scalaXmlIfNecessary, + libs ++= Seq( + Deps.fastParse % "shaded", + Deps.jsoup + ), + generatePropertyFile ) .jsSettings( - libraryDependencies += "com.lihaoyi" %%% "fastparse" % "0.4.2" + libs ++= Seq( + CrossDeps.fastParse.value, + CrossDeps.scalaJsDom.value + ) ) .settings( + shared, name := "coursier", - libraryDependencies ++= Seq( - "org.scalaz" %%% "scalaz-core" % scalazVersion - ), - mimaBinaryIssueFilters ++= { - import com.typesafe.tools.mima.core._ - - Seq( - ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.maven.MavenRepository.defaultPublications"), - ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.maven.MavenRepository.defaultPackaging"), - ProblemFilters.exclude[MissingClassProblem]("coursier.maven.MavenSource$DocSourcesArtifactExtensions"), - ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.core.compatibility.package.listWebPageDirectoryElements"), - ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.core.compatibility.package.listWebPageSubDirectories"), - ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.core.compatibility.package.listWebPageFiles"), - ProblemFilters.exclude[MissingTypesProblem]("coursier.core.Project$"), - ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.core.Project.apply"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]("coursier.core.Project.copy$default$13"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]("coursier.core.Project.copy$default$12"), - ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.core.Project.copy"), - ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.core.Project.this"), - ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.maven.MavenRepository.copy$default$5"), - ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.maven.MavenRepository.packagingBlacklist"), - ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.maven.MavenRepository.copy"), - ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.maven.MavenRepository.this"), - ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.maven.MavenRepository.apply$default$5"), - ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.maven.MavenRepository.ignorePackaging"), - ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.maven.MavenRepository.$default$5"), - ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.maven.MavenRepository.apply"), - ProblemFilters.exclude[FinalClassProblem]("coursier.core.Activation$Os"), - ProblemFilters.exclude[FinalClassProblem]("coursier.core.Version"), - ProblemFilters.exclude[FinalClassProblem]("coursier.core.Authentication"), - ProblemFilters.exclude[FinalClassProblem]("coursier.core.VersionInterval"), - ProblemFilters.exclude[FinalClassProblem]("coursier.ivy.Pattern"), - ProblemFilters.exclude[FinalClassProblem]("coursier.ivy.Pattern$Chunk$Opt"), - ProblemFilters.exclude[FinalClassProblem]("coursier.ivy.PropertiesPattern$ChunkOrProperty$Const"), - ProblemFilters.exclude[FinalClassProblem]("coursier.ivy.PropertiesPattern$ChunkOrProperty$Opt"), - ProblemFilters.exclude[FinalClassProblem]("coursier.ivy.PropertiesPattern"), - ProblemFilters.exclude[FinalClassProblem]("coursier.ivy.Pattern$Chunk$Var"), - ProblemFilters.exclude[FinalClassProblem]("coursier.ivy.IvyRepository"), - ProblemFilters.exclude[FinalClassProblem]("coursier.ivy.Pattern$Chunk$Const"), - ProblemFilters.exclude[FinalClassProblem]("coursier.ivy.PropertiesPattern$ChunkOrProperty$Prop"), - ProblemFilters.exclude[FinalClassProblem]("coursier.ivy.PropertiesPattern$ChunkOrProperty$Var"), - ProblemFilters.exclude[FinalClassProblem]("coursier.maven.MavenRepository"), - ProblemFilters.exclude[FinalClassProblem]("coursier.maven.MavenSource"), - 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"), - ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.core.Resolution.this"), - ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.core.Activation.copy"), - ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.core.Activation.this"), - 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") - ) - } - ) - .jvmSettings( - libraryDependencies ++= - Seq( - "org.jsoup" % "jsoup" % "1.10.2" - ) ++ { - if (scalaBinaryVersion.value == "2.10") Seq() - else Seq( - "org.scala-lang.modules" %% "scala-xml" % "1.0.6" - ) - }, - resourceGenerators.in(Compile) += { - (target, version).map { (dir, ver) => - import sys.process._ - - val f = dir / "coursier.properties" - dir.mkdirs() - - val p = new java.util.Properties - - p.setProperty("version", ver) - p.setProperty("commit-hash", Seq("git", "rev-parse", "HEAD").!!.trim) - - val w = new FileOutputStream(f) - p.store(w, "Coursier properties") - w.close() - - println(s"Wrote $f") - - Seq(f) - }.taskValue - } - ) - .jsSettings( - libraryDependencies ++= Seq( - "org.scala-js" %%% "scalajs-dom" % "0.9.1" - ) + libs += CrossDeps.scalazCore.value, + Mima.previousArtifacts, + Mima.coreFilters ) lazy val coreJvm = core.jvm @@ -139,234 +37,79 @@ lazy val coreJs = core.js lazy val `fetch-js` = project .enablePlugins(ScalaJSPlugin) .dependsOn(coreJs) - .settings(commonSettings) - .settings(noPublishSettings) .settings( - name := "coursier-fetch-js" + shared, + dontPublish, + coursierPrefix ) lazy val tests = crossProject .dependsOn(core) - .settings(commonSettings) - .settings(noPublishSettings) - .configs(IntegrationTest) - .settings(Defaults.itSettings) - .settings( - name := "coursier-tests", - libraryDependencies += { - val asyncVersion = - if (scalaBinaryVersion.value == "2.10") - "0.9.5" - else - "0.9.6" - - "org.scala-lang.modules" %% "scala-async" % asyncVersion % "provided" - }, - 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") - ) + .jvmConfigure(_.dependsOn(cache % "test")) + .jsConfigure(_.dependsOn(`fetch-js` % "test")) .jsSettings( - scalaJSStage in Global := FastOptStage + scalaJSStage.in(Global) := FastOptStage + ) + .configs(Integration) + .settings( + shared, + dontPublish, + hasITs, + coursierPrefix, + libs += Deps.scalaAsync.value, + utest, + sharedTestResources ) -lazy val testsJvm = tests.jvm.dependsOn(cache % "test") -lazy val testsJs = tests.js.dependsOn(`fetch-js` % "test") +lazy val testsJvm = tests.jvm +lazy val testsJs = tests.js lazy val cache = project .dependsOn(coreJvm) - .settings(commonSettings) - .settings(mimaPreviousArtifactSettings) .settings( - name := "coursier-cache", - libraryDependencies += "org.scalaz" %% "scalaz-concurrent" % scalazVersion, - mimaBinaryIssueFilters ++= { - import com.typesafe.tools.mima.core._ - - Seq( - ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.TermDisplay#UpdateDisplayRunnable.cleanDisplay"), - ProblemFilters.exclude[FinalClassProblem]("coursier.TermDisplay$DownloadInfo"), - ProblemFilters.exclude[FinalClassProblem]("coursier.TermDisplay$CheckUpdateInfo"), - ProblemFilters.exclude[FinalClassProblem]("coursier.util.Base64$B64Scheme"), - 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") - ) - } + shared, + Mima.previousArtifacts, + coursierPrefix, + libs += Deps.scalazConcurrent, + Mima.cacheFilters ) lazy val bootstrap = project - .settings(scalaVersionAgnosticCommonSettings) - .settings(noPublishSettings) .settings( - name := "coursier-bootstrap", - artifactName := { - val artifactName0 = artifactName.value - (sv, m, artifact) => - if (artifact.`type` == "jar" && artifact.extension == "jar") - "bootstrap.jar" - else - artifactName0(sv, m, artifact) - }, - crossPaths := false, - autoScalaLibrary := false + pureJava, + dontPublish, + renameMainJar("bootstrap.jar") ) lazy val cli = project .dependsOn(coreJvm, cache) - .settings(commonSettings) - .settings(noPublishForScalaVersionSettings("2.10", "2.12")) - .settings(packAutoSettings) - .settings(proguardSettings) .settings( - name := "coursier-cli", - libraryDependencies ++= { + shared, + dontPublishIn("2.10", "2.12"), + generatePack, + proguard, + coursierPrefix, + libs ++= { if (scalaBinaryVersion.value == "2.11") - Seq("com.github.alexarchambault" %% "case-app" % "1.1.3") + Seq(Deps.caseApp) else Seq() }, - packExcludeArtifactTypes += "pom", - resourceGenerators in Compile += packageBin.in(bootstrap).in(Compile).map { jar => - import java.nio.file.Files - import java.nio.charset.StandardCharsets - - val content = Files.readAllBytes(jar.toPath) - val header = - """#!/usr/bin/env sh - |exec java $JAVA_OPTS -noverify -jar "$0" "$@" - """.stripMargin - - Files.write(jar.toPath, header.getBytes(StandardCharsets.UTF_8) ++ content) - - Seq(jar) - }.taskValue, - ProguardKeys.proguardVersion in Proguard := "5.3", - ProguardKeys.options in Proguard ++= Seq( - "-dontwarn", - "-keep class coursier.cli.Coursier {\n public static void main(java.lang.String[]);\n}", - "-keep class coursier.cli.IsolatedClassLoader {\n public java.lang.String[] getIsolationTargets();\n}", - "-adaptresourcefilenames **.properties" - ), - javaOptions in (Proguard, ProguardKeys.proguard) := Seq("-Xmx3172M"), - artifactPath in Proguard := (ProguardKeys.proguardDirectory in Proguard).value / "coursier-standalone.jar", - artifacts ++= { - if (scalaBinaryVersion.value == "2.11") - Seq( - Artifact( - moduleName.value, - "jar", - "jar", - "standalone" - ) - ) - else - Nil - }, - packagedArtifacts <++= { - ( - moduleName, - scalaBinaryVersion, - ProguardKeys.proguard in Proguard, - packageBin.in(bootstrap) in Compile - ).map { - (mod, sbv, files, bootstrapJar) => - if (sbv == "2.11") { - import java.util.zip.{ ZipEntry, ZipOutputStream, ZipInputStream } - import java.io.{ ByteArrayOutputStream, FileInputStream, FileOutputStream, File, InputStream, IOException } - - val f0 = files match { - case Seq(f) => f - case Seq() => - throw new Exception("Found no proguarded files. Expected one.") - case _ => - throw new Exception("Found several proguarded files. Don't know how to publish all of them.") - } - - val f = new File(f0.getParentFile, f0.getName.stripSuffix(".jar") + "-with-bootstrap.jar") - - val is = new FileInputStream(f0) - val os = new FileOutputStream(f) - val bootstrapZip = new ZipInputStream(is) - val outputZip = new ZipOutputStream(os) - - def readFullySync(is: InputStream) = { - val buffer = new ByteArrayOutputStream - val data = Array.ofDim[Byte](16384) - - var nRead = is.read(data, 0, data.length) - while (nRead != -1) { - buffer.write(data, 0, nRead) - nRead = is.read(data, 0, data.length) - } - - buffer.flush() - buffer.toByteArray - } - - def zipEntries(zipStream: ZipInputStream): Iterator[(ZipEntry, Array[Byte])] = - new Iterator[(ZipEntry, Array[Byte])] { - private var nextEntry = Option.empty[ZipEntry] - private def update() = - nextEntry = Option(zipStream.getNextEntry) - - update() - - def hasNext = nextEntry.nonEmpty - def next() = { - val ent = nextEntry.get - val data = readFullySync(zipStream) - - update() - - (ent, data) - } - } - - for ((ent, data) <- zipEntries(bootstrapZip)) { - outputZip.putNextEntry(ent) - outputZip.write(data) - outputZip.closeEntry() - } - - outputZip.putNextEntry(new ZipEntry("bootstrap.jar")) - outputZip.write(readFullySync(new FileInputStream(bootstrapJar))) - outputZip.closeEntry() - - outputZip.close() - - is.close() - os.close() - - - Map( - // FIXME Same Artifact as above - Artifact( - mod, - "jar", - "jar", - "standalone" - ) -> f - ) - } else - Map.empty[Artifact, File] - } - } + addBootstrapJarAsResource, + proguardedCli ) lazy val web = project .enablePlugins(ScalaJSPlugin) .dependsOn(coreJs, `fetch-js`) - .settings(commonSettings) - .settings(noPublishSettings) .settings( - libraryDependencies ++= { + shared, + dontPublish, + libs ++= { if (scalaBinaryVersion.value == "2.11") Seq( - "be.doeraene" %%% "scalajs-jquery" % "0.9.1", - "com.github.japgolly.scalajs-react" %%% "core" % "0.9.0" + CrossDeps.scalaJsJquery.value, + CrossDeps.scalaJsReact.value ) else Seq() @@ -379,119 +122,97 @@ lazy val web = project else dir / "dummy" }, - test in Test := (), - testOnly in Test := (), - resolvers += "Webjars Bintray" at "https://dl.bintray.com/webjars/maven/", + noTests, + webjarBintrayRepository, jsDependencies ++= Seq( - ("org.webjars.bower" % "bootstrap" % "3.3.4" intransitive()) / "bootstrap.min.js" commonJSName "Bootstrap", - ("org.webjars.bower" % "react" % "0.12.2" intransitive()) / "react-with-addons.js" commonJSName "React", - ("org.webjars.bower" % "bootstrap-treeview" % "1.2.0" intransitive()) / "bootstrap-treeview.min.js" commonJSName "Treeview", - ("org.webjars.bower" % "raphael" % "2.1.4" intransitive()) / "raphael-min.js" commonJSName "Raphael" + WebDeps.bootstrap + .intransitive() + ./("bootstrap.min.js") + .commonJSName("Bootstrap"), + WebDeps.react + .intransitive() + ./("react-with-addons.js") + .commonJSName("React"), + WebDeps.bootstrapTreeView + .intransitive() + ./("bootstrap-treeview.min.js") + .commonJSName("Treeview"), + WebDeps.raphael + .intransitive() + ./("raphael-min.js") + .commonJSName("Raphael") ) ) lazy val doc = project .dependsOn(coreJvm, cache) - .settings(commonSettings) - .settings(noPublishSettings) - .settings(tutSettings) .settings( + shared, + dontPublish, + tutSettings, tutSourceDirectory := baseDirectory.value, - tutTargetDirectory := baseDirectory.value / ".." + tutTargetDirectory := baseDirectory.in(LocalRootProject).value ) // Don't try to compile that if you're not in 2.10 lazy val `sbt-coursier` = project .dependsOn(coreJvm, cache) - .settings(pluginSettings) + .settings(plugin) // Don't try to compile that if you're not in 2.10 lazy val `sbt-shading` = project - .enablePlugins(_root_.coursier.ShadingPlugin) + .enablePlugins(ShadingPlugin) .dependsOn(`sbt-coursier`) - .settings(pluginSettings) .settings( - resolvers += Resolver.mavenLocal, - libraryDependencies ++= { - val coursierJarjarVersion = "1.0.1-coursier-SNAPSHOT" - def coursierJarjarFoundInM2 = (file(sys.props("user.home")) / s".m2/repository/org/anarres/jarjar/jarjar-core/$coursierJarjarVersion").exists() - - val jarjarVersion = - if (sys.env.contains("CI") || coursierJarjarFoundInM2 || !isSnapshot.value) - coursierJarjarVersion - else { - val fallback = "1.0.0" - - // streams.value.log.warn( // "a setting cannot depend on a task" - scala.Console.err.println( - s"""Warning: using jarjar $fallback, which doesn't properly shade Scala JARs (classes with '$$' aren't shaded). - |See the instructions around - |https://github.com/coursier/coursier/blob/630a780487d662dd994ed1c3246895a22c00cf21/scripts/travis.sh#L40 - |to use a version fine with Scala JARs.""".stripMargin - ) - - fallback - } - - Seq( - "org.anarres.jarjar" % "jarjar-core" % jarjarVersion % "shaded", - // dependencies of jarjar-core - directly depending on these so that they don't get shaded - "com.google.code.findbugs" % "jsr305" % "2.0.2", - "org.ow2.asm" % "asm-commons" % "5.0.3", - "org.ow2.asm" % "asm-util" % "5.0.3", - "org.slf4j" % "slf4j-api" % "1.7.12" - ) - }, - shadingSettings + plugin, + shading, + localM2Repository, // for a possibly locally published jarjar + libs += Deps.jarjar.value % "shaded", + // dependencies of jarjar-core - directly depending on these so that they don't get shaded + libs ++= Deps.jarjarTransitiveDeps ) lazy val `sbt-launcher` = project .dependsOn(cache) - .settings(commonSettings) - .settings(packAutoSettings) .settings( - libraryDependencies ++= Seq( - "com.github.alexarchambault" %% "case-app" % "1.1.3", - "org.scala-sbt" % "launcher-interface" % "1.0.0", - "com.typesafe" % "config" % "1.3.1" - ), - packExcludeArtifactTypes += "pom" + shared, + generatePack, + libs ++= Seq( + Deps.caseApp, + Deps.sbtLauncherInterface, + Deps.typesafeConfig + ) ) -val http4sVersion = "0.8.6" - lazy val `http-server` = project - .settings(commonSettings) - .settings(packAutoSettings) - .settings(noPublishForScalaVersionSettings("2.10", "2.12")) .settings( + shared, + generatePack, + dontPublishIn("2.10", "2.12"), name := "http-server-java7", - libraryDependencies ++= { + libs ++= { if (scalaBinaryVersion.value == "2.11") Seq( - "org.http4s" %% "http4s-blazeserver" % http4sVersion, - "org.http4s" %% "http4s-dsl" % http4sVersion, - "org.slf4j" % "slf4j-nop" % "1.7.22", - "com.github.alexarchambault" %% "case-app" % "1.1.3" + Deps.http4sBlazeServer, + Deps.http4sDsl, + Deps.slf4jNop, + Deps.caseApp ) else Seq() - }, - packExcludeArtifactTypes += "pom" + } ) lazy val okhttp = project .dependsOn(cache) - .settings(commonSettings) .settings( - name := "coursier-okhttp", - libraryDependencies ++= Seq( - "com.squareup.okhttp" % "okhttp-urlconnection" % "2.7.5" - ) + shared, + coursierPrefix, + libs += Deps.okhttpUrlConnection ) lazy val echo = project - .settings(commonSettings) + .settings(shared) lazy val jvm = project .aggregate( @@ -508,10 +229,9 @@ lazy val jvm = project okhttp, echo ) - .settings(commonSettings) - .settings(noPublishSettings) - .settings(releaseSettings) .settings( + shared, + dontPublish, moduleName := "coursier-jvm" ) @@ -522,14 +242,14 @@ lazy val js = project testsJs, web ) - .settings(commonSettings) - .settings(noPublishSettings) - .settings(releaseSettings) .settings( + shared, + dontPublish, moduleName := "coursier-js" ) -lazy val `coursier` = project.in(file(".")) +lazy val coursier = project + .in(file(".")) .aggregate( coreJvm, coreJs, @@ -547,158 +267,55 @@ lazy val `coursier` = project.in(file(".")) `http-server`, okhttp ) - .settings(commonSettings) - .settings(noPublishSettings) - .settings(releaseSettings) .settings( + shared, + dontPublish, 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/coursier/coursier")), - scmInfo := Some(ScmInfo( - url("https://github.com/coursier/coursier.git"), - "scm:git:github.com/coursier/coursier.git", - Some("scm:git:git@github.com:coursier/coursier.git") - )), - pomExtra := { - - - alexarchambault - Alexandre Archambault - https://github.com/alexarchambault - - - }, - 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 addBootstrapJarAsResource = { + resourceGenerators.in(Compile) += packageBin.in(bootstrap).in(Compile).map(Seq(_)).taskValue +} + +lazy val addBootstrapInProguardedJar = { + ProguardKeys.proguard.in(Proguard) := { + val bootstrapJar = packageBin.in(bootstrap).in(Compile).value + val source = proguardedJar.value + + val dest = source.getParentFile / (source.getName.stripSuffix(".jar") + "-with-bootstrap.jar") + + ZipUtil.addToZip(source, dest, Seq("bootstrap.jar" -> bootstrapJar)) + + Seq(dest) } -) +} -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 "https://dl.bintray.com/scalaz/releases", - Resolver.sonatypeRepo("releases") +lazy val proguardedCli = Seq( + ProguardKeys.proguardVersion.in(Proguard) := "5.3", + ProguardKeys.options.in(Proguard) ++= Seq( + "-dontwarn", + "-keep class coursier.cli.Coursier {\n public static void main(java.lang.String[]);\n}", + "-keep class coursier.cli.IsolatedClassLoader {\n public java.lang.String[] getIsolationTargets();\n}", + "-adaptresourcefilenames **.properties" ), - 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() - } - }, - 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)) + javaOptions.in(Proguard, ProguardKeys.proguard) := Seq("-Xmx3172M"), + artifactPath.in(Proguard) := ProguardKeys.proguardDirectory.in(Proguard).value / "coursier-standalone.jar", + artifacts ++= { + if (scalaBinaryVersion.value == "2.11") + Seq(proguardedArtifact.value) else - Seq() + Nil + }, + addBootstrapInProguardedJar, + packagedArtifacts ++= { + if (scalaBinaryVersion.value == "2.11") + Map(proguardedArtifact.value -> proguardedJar.value) + else + Map() } ) -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) - } -) - -lazy val shadingSettings = - inConfig(Shading)(PgpSettings.projectSettings) ++ - // ytf does this have to be repeated here? - // Can't figure out why configuration get lost without this in particular... - _root_.coursier.ShadingPlugin.projectSettings ++ - Seq( - shadingNamespace := "coursier.shaded", - publish := publish.in(Shading).value, - publishLocal := publishLocal.in(Shading).value, - PgpKeys.publishSigned := PgpKeys.publishSigned.in(Shading).value, - PgpKeys.publishLocalSigned := PgpKeys.publishLocalSigned.in(Shading).value - ) +lazy val sharedTestResources = { + unmanagedResourceDirectories.in(Test) += baseDirectory.in(LocalRootProject).value / "tests" / "shared" / "src" / "test" / "resources" +} diff --git a/project/Aliases.scala b/project/Aliases.scala new file mode 100644 index 000000000..838db5c9c --- /dev/null +++ b/project/Aliases.scala @@ -0,0 +1,21 @@ + +import sbt._ +import sbt.Defaults.itSettings +import sbt.Keys._ +import sbt.ScriptedPlugin.scriptedSettings + +import com.typesafe.sbt.SbtProguard.proguardSettings + +object Aliases { + + def libs = libraryDependencies + + def withScriptedTests = scriptedSettings + + def hasITs = itSettings + + def proguard = proguardSettings + + def ShadingPlugin = coursier.ShadingPlugin + +} diff --git a/project/CoursierSettings.scala b/project/CoursierSettings.scala new file mode 100644 index 000000000..5e0a5a0a8 --- /dev/null +++ b/project/CoursierSettings.scala @@ -0,0 +1,204 @@ + +import sbt._ +import sbt.Keys._ +import sbt.ScriptedPlugin._ + +import com.typesafe.sbt.pgp._ +import com.typesafe.sbt.SbtProguard._ +import coursier.ShadingPlugin.autoImport._ + +import xerial.sbt.Pack.{packAutoSettings, packExcludeArtifactTypes} + +import Aliases._ + +object CoursierSettings { + + lazy val scalazBintrayRepository = { + resolvers += "Scalaz Bintray Repo" at "https://dl.bintray.com/scalaz/releases" + } + + def sonatypeRepository(name: String) = { + resolvers += Resolver.sonatypeRepo("releases") + } + + lazy val localM2Repository = { + resolvers += Resolver.mavenLocal + } + + lazy val javaScalaPluginShared = Publish.released ++ Seq( + organization := "io.get-coursier", + scalazBintrayRepository, + sonatypeRepository("releases"), + 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() + } + }, + javacOptions in Keys.doc := Seq() + ) + + lazy val shared = javaScalaPluginShared ++ Seq( + scalaVersion := "2.12.1", + crossScalaVersions := Seq("2.12.1", "2.11.8", "2.10.6"), + libs ++= { + if (scalaBinaryVersion.value == "2.10") + Seq(compilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross CrossVersion.full)) + else + Seq() + } + ) + + lazy val pureJava = javaScalaPluginShared ++ Seq( + crossPaths := false, + autoScalaLibrary := false + ) + + lazy val generatePropertyFile = + resourceGenerators.in(Compile) += { + (target, version).map { (dir, ver) => + import sys.process._ + + val f = dir / "coursier.properties" + dir.mkdirs() + + val p = new java.util.Properties + + p.setProperty("version", ver) + p.setProperty("commit-hash", Seq("git", "rev-parse", "HEAD").!!.trim) + + val w = new java.io.FileOutputStream(f) + p.store(w, "Coursier properties") + w.close() + + println(s"Wrote $f") + + Seq(f) + }.taskValue + } + + lazy val coursierPrefix = { + name := "coursier-" + name.value + } + + lazy val scalaXmlIfNecessary = Seq( + libs ++= { + if (scalaBinaryVersion.value == "2.10") Seq() + else Seq(Deps.scalaXml) + } + ) + + lazy val quasiQuotesIfNecessary = Seq( + libs ++= { + if (scalaBinaryVersion.value == "2.10") + // directly depending on that one so that it doesn't get shaded + Seq(Deps.quasiQuotes) + else + Nil + } + ) + + lazy val noTests = Seq( + test in Test := (), + testOnly in Test := () + ) + + lazy val utest = Seq( + libs += CrossDeps.utest.value % "test", + testFrameworks += new TestFramework("utest.runner.Framework") + ) + + lazy val webjarBintrayRepository = { + resolvers += "Webjars Bintray" at "https://dl.bintray.com/webjars/maven/" + } + + def renameMainJar(name: String) = { + artifactName := { + val artifactName0 = artifactName.value + (sv, m, artifact) => + if (artifact.`type` == "jar" && artifact.extension == "jar") + name + else + artifactName0(sv, m, artifact) + } + } + + lazy val plugin = + javaScalaPluginShared ++ + Publish.dontPublishIn("2.11", "2.12") ++ + withScriptedTests ++ + 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 shading = + inConfig(_root_.coursier.ShadingPlugin.Shading)(PgpSettings.projectSettings) ++ + // ytf does this have to be repeated here? + // Can't figure out why configuration get lost without this in particular... + _root_.coursier.ShadingPlugin.projectSettings ++ + Seq( + shadingNamespace := "coursier.shaded", + publish := publish.in(Shading).value, + publishLocal := publishLocal.in(Shading).value, + PgpKeys.publishSigned := PgpKeys.publishSigned.in(Shading).value, + PgpKeys.publishLocalSigned := PgpKeys.publishLocalSigned.in(Shading).value + ) + + lazy val generatePack = packAutoSettings :+ { + packExcludeArtifactTypes += "pom" + } + + lazy val proguardedArtifact = Def.setting { + Artifact( + moduleName.value, + "jar", + "jar", + "standalone" + ) + } + + lazy val proguardedJar = Def.task { + + val results = ProguardKeys.proguard.in(Proguard).value + + results match { + case Seq(f) => f + case Seq() => + throw new Exception("Found no proguarded files. Expected one.") + case _ => + throw new Exception("Found several proguarded files. Don't know how to publish all of them.") + } + } + + lazy val Integration = config("it").extend(Test) + +} diff --git a/project/CrossDeps.scala b/project/CrossDeps.scala new file mode 100644 index 000000000..863d2bd1d --- /dev/null +++ b/project/CrossDeps.scala @@ -0,0 +1,20 @@ + +import sbt._ +import sbt.Keys._ + +import org.scalajs.sbtplugin.ScalaJSPlugin.autoImport._ + +object CrossDeps { + + import Def.setting + + // The setting / .value hoop-and-loop is necessary because of the expansion of the %%% macro, which references + // other settings. + + def fastParse = setting("com.lihaoyi" %%% "fastparse" % "0.4.2") + def scalazCore = setting("org.scalaz" %%% "scalaz-core" % SharedVersions.scalaz) + def scalaJsDom = setting("org.scala-js" %%% "scalajs-dom" % "0.9.1") + def utest = setting("com.lihaoyi" %%% "utest" % "0.4.5") + def scalaJsJquery = setting("be.doeraene" %%% "scalajs-jquery" % "0.9.1") + def scalaJsReact = setting("com.github.japgolly.scalajs-react" %%% "core" % "0.9.0") +} diff --git a/project/Deps.scala b/project/Deps.scala new file mode 100644 index 000000000..2257162c7 --- /dev/null +++ b/project/Deps.scala @@ -0,0 +1,59 @@ + +import sbt._ +import sbt.Keys._ + +object Deps { + + def quasiQuotes = "org.scalamacros" %% "quasiquotes" % "2.1.0" + def fastParse = "com.lihaoyi" %% "fastparse" % "0.4.2" + def jsoup = "org.jsoup" % "jsoup" % "1.10.2" + def scalaXml = "org.scala-lang.modules" %% "scala-xml" % "1.0.6" + def scalazConcurrent = "org.scalaz" %% "scalaz-concurrent" % SharedVersions.scalaz + def caseApp = "com.github.alexarchambault" %% "case-app" % "1.1.3" + def http4sBlazeServer = "org.http4s" %% "http4s-blazeserver" % SharedVersions.http4s + def http4sDsl = "org.http4s" %% "http4s-dsl" % SharedVersions.http4s + def slf4jNop = "org.slf4j" % "slf4j-nop" % "1.7.22" + def okhttpUrlConnection = "com.squareup.okhttp" % "okhttp-urlconnection" % "2.7.5" + def sbtLauncherInterface = "org.scala-sbt" % "launcher-interface" % "1.0.0" + def typesafeConfig = "com.typesafe" % "config" % "1.3.1" + + def scalaAsync = Def.setting { + + val version = + if (scalaBinaryVersion.value == "2.10") "0.9.5" + else "0.9.6" + + "org.scala-lang.modules" %% "scala-async" % version + } + + def jarjar = Def.setting { + val coursierJarjarVersion = "1.0.1-coursier-SNAPSHOT" + def coursierJarjarFoundInM2 = (file(sys.props("user.home")) / s".m2/repository/org/anarres/jarjar/jarjar-core/$coursierJarjarVersion").exists() + + val jarjarVersion = + if (sys.env.contains("CI") || coursierJarjarFoundInM2 || !isSnapshot.value) + coursierJarjarVersion + else { + val fallback = "1.0.0" + + // streams.value.log.warn( // "a setting cannot depend on a task" + scala.Console.err.println( + s"""Warning: using jarjar $fallback, which doesn't properly shade Scala JARs (classes with '$$' aren't shaded). + |See the instructions around + |https://github.com/coursier/coursier/blob/630a780487d662dd994ed1c3246895a22c00cf21/scripts/travis.sh#L40 + |to use a version fine with Scala JARs.""".stripMargin + ) + + fallback + } + + "org.anarres.jarjar" % "jarjar-core" % jarjarVersion + } + + def jarjarTransitiveDeps = Seq( + "com.google.code.findbugs" % "jsr305" % "2.0.2", + "org.ow2.asm" % "asm-commons" % "5.0.3", + "org.ow2.asm" % "asm-util" % "5.0.3", + "org.slf4j" % "slf4j-api" % "1.7.12" + ) +} \ No newline at end of file diff --git a/project/Mima.scala b/project/Mima.scala new file mode 100644 index 000000000..8ca92e7c3 --- /dev/null +++ b/project/Mima.scala @@ -0,0 +1,101 @@ + +import sbt._ +import sbt.Keys._ + +import com.typesafe.tools.mima.plugin.MimaKeys._ + +object Mima { + + def binaryCompatibilityVersion = "1.0.0-M14" + def binaryCompatibility212Version = "1.0.0-M15" + + + lazy val previousArtifacts = Seq( + mimaPreviousArtifacts := { + val version = scalaBinaryVersion.value match { + case "2.12" => binaryCompatibility212Version + case _ => binaryCompatibilityVersion + } + + Set(organization.value %% moduleName.value % version) + } + ) + + lazy val coreFilters = { + mimaBinaryIssueFilters ++= { + import com.typesafe.tools.mima.core._ + + Seq( + ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.maven.MavenRepository.defaultPublications"), + ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.maven.MavenRepository.defaultPackaging"), + ProblemFilters.exclude[MissingClassProblem]("coursier.maven.MavenSource$DocSourcesArtifactExtensions"), + ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.core.compatibility.package.listWebPageDirectoryElements"), + ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.core.compatibility.package.listWebPageSubDirectories"), + ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.core.compatibility.package.listWebPageFiles"), + ProblemFilters.exclude[MissingTypesProblem]("coursier.core.Project$"), + ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.core.Project.apply"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]("coursier.core.Project.copy$default$13"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]("coursier.core.Project.copy$default$12"), + ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.core.Project.copy"), + ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.core.Project.this"), + ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.maven.MavenRepository.copy$default$5"), + ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.maven.MavenRepository.packagingBlacklist"), + ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.maven.MavenRepository.copy"), + ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.maven.MavenRepository.this"), + ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.maven.MavenRepository.apply$default$5"), + ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.maven.MavenRepository.ignorePackaging"), + ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.maven.MavenRepository.$default$5"), + ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.maven.MavenRepository.apply"), + ProblemFilters.exclude[FinalClassProblem]("coursier.core.Activation$Os"), + ProblemFilters.exclude[FinalClassProblem]("coursier.core.Version"), + ProblemFilters.exclude[FinalClassProblem]("coursier.core.Authentication"), + ProblemFilters.exclude[FinalClassProblem]("coursier.core.VersionInterval"), + ProblemFilters.exclude[FinalClassProblem]("coursier.ivy.Pattern"), + ProblemFilters.exclude[FinalClassProblem]("coursier.ivy.Pattern$Chunk$Opt"), + ProblemFilters.exclude[FinalClassProblem]("coursier.ivy.PropertiesPattern$ChunkOrProperty$Const"), + ProblemFilters.exclude[FinalClassProblem]("coursier.ivy.PropertiesPattern$ChunkOrProperty$Opt"), + ProblemFilters.exclude[FinalClassProblem]("coursier.ivy.PropertiesPattern"), + ProblemFilters.exclude[FinalClassProblem]("coursier.ivy.Pattern$Chunk$Var"), + ProblemFilters.exclude[FinalClassProblem]("coursier.ivy.IvyRepository"), + ProblemFilters.exclude[FinalClassProblem]("coursier.ivy.Pattern$Chunk$Const"), + ProblemFilters.exclude[FinalClassProblem]("coursier.ivy.PropertiesPattern$ChunkOrProperty$Prop"), + ProblemFilters.exclude[FinalClassProblem]("coursier.ivy.PropertiesPattern$ChunkOrProperty$Var"), + ProblemFilters.exclude[FinalClassProblem]("coursier.maven.MavenRepository"), + ProblemFilters.exclude[FinalClassProblem]("coursier.maven.MavenSource"), + 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"), + ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.core.Resolution.this"), + ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.core.Activation.copy"), + ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.core.Activation.this"), + 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") + ) + } + } + + lazy val cacheFilters = { + mimaBinaryIssueFilters ++= { + import com.typesafe.tools.mima.core._ + + Seq( + ProblemFilters.exclude[DirectMissingMethodProblem]("coursier.TermDisplay#UpdateDisplayRunnable.cleanDisplay"), + ProblemFilters.exclude[FinalClassProblem]("coursier.TermDisplay$DownloadInfo"), + ProblemFilters.exclude[FinalClassProblem]("coursier.TermDisplay$CheckUpdateInfo"), + ProblemFilters.exclude[FinalClassProblem]("coursier.util.Base64$B64Scheme"), + 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") + ) + } + } + +} diff --git a/project/Publish.scala b/project/Publish.scala new file mode 100644 index 000000000..a18005312 --- /dev/null +++ b/project/Publish.scala @@ -0,0 +1,67 @@ + +import sbt._ +import sbt.Keys._ + +object Publish { + + lazy val dontPublish = Seq( + publish := (), + publishLocal := (), + publishArtifact := false + ) + + def dontPublishIn(sbv: String*) = Seq( + publish := { + if (!sbv.contains(scalaBinaryVersion.value)) + publish.value + }, + publishLocal := { + if (!sbv.contains(scalaBinaryVersion.value)) + publishLocal.value + }, + publishArtifact := { + !sbv.contains(scalaBinaryVersion.value) && publishArtifact.value + } + ) + + private def pomStuff = Seq( + licenses := Seq("Apache 2.0" -> url("http://opensource.org/licenses/Apache-2.0")), + homepage := Some(url("https://github.com/coursier/coursier")), + scmInfo := Some(ScmInfo( + url("https://github.com/coursier/coursier.git"), + "scm:git:github.com/coursier/coursier.git", + Some("scm:git:git@github.com:coursier/coursier.git") + )), + pomExtra := { + + + alexarchambault + Alexandre Archambault + https://github.com/alexarchambault + + + } + ) + + private def pushToSonatypeStuff = Seq( + publishMavenStyle := true, + 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 released = pomStuff ++ pushToSonatypeStuff + +} diff --git a/project/SharedVersions.scala b/project/SharedVersions.scala new file mode 100644 index 000000000..3442e7b89 --- /dev/null +++ b/project/SharedVersions.scala @@ -0,0 +1,9 @@ + +object SharedVersions { + + val scalaz = "7.2.8" + + // last http4s version compatible with Java 7 (Travis-based Mac CI still on Java 7...) + val http4s = "0.8.6" + +} \ No newline at end of file diff --git a/project/WebDeps.scala b/project/WebDeps.scala new file mode 100644 index 000000000..fb2de7df1 --- /dev/null +++ b/project/WebDeps.scala @@ -0,0 +1,10 @@ + +import sbt._ +import sbt.Keys._ + +object WebDeps { + def bootstrap = "org.webjars.bower" % "bootstrap" % "3.3.4" + def react = "org.webjars.bower" % "react" % "0.12.2" + def bootstrapTreeView = "org.webjars.bower" % "bootstrap-treeview" % "1.2.0" + def raphael = "org.webjars.bower" % "raphael" % "2.1.4" +} diff --git a/project/ZipUtil.scala b/project/ZipUtil.scala new file mode 100644 index 000000000..73032afb5 --- /dev/null +++ b/project/ZipUtil.scala @@ -0,0 +1,66 @@ + +import java.util.zip.{ ZipEntry, ZipOutputStream, ZipInputStream } +import java.io.{ ByteArrayOutputStream, FileInputStream, FileOutputStream, File, InputStream, IOException } + +object ZipUtil { + + def addToZip(sourceZip: File, destZip: File, extra: Seq[(String, File)]): Unit = { + + val is = new FileInputStream(sourceZip) + val os = new FileOutputStream(destZip) + val bootstrapZip = new ZipInputStream(is) + val outputZip = new ZipOutputStream(os) + + def readFullySync(is: InputStream) = { + val buffer = new ByteArrayOutputStream + val data = Array.ofDim[Byte](16384) + + var nRead = is.read(data, 0, data.length) + while (nRead != -1) { + buffer.write(data, 0, nRead) + nRead = is.read(data, 0, data.length) + } + + buffer.flush() + buffer.toByteArray + } + + def zipEntries(zipStream: ZipInputStream): Iterator[(ZipEntry, Array[Byte])] = + new Iterator[(ZipEntry, Array[Byte])] { + private var nextEntry = Option.empty[ZipEntry] + private def update() = + nextEntry = Option(zipStream.getNextEntry) + + update() + + def hasNext = nextEntry.nonEmpty + def next() = { + val ent = nextEntry.get + val data = readFullySync(zipStream) + + update() + + (ent, data) + } + } + + for ((ent, data) <- zipEntries(bootstrapZip)) { + outputZip.putNextEntry(ent) + outputZip.write(data) + outputZip.closeEntry() + } + + for ((dest, file) <- extra) { + outputZip.putNextEntry(new ZipEntry(dest)) + outputZip.write(readFullySync(new FileInputStream(file))) + outputZip.closeEntry() + } + + outputZip.close() + + is.close() + os.close() + + } + +}