aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Christopher Vogt <oss.nsp@cvogt.org>2017-03-06 21:43:58 -0500
committerGitHub <noreply@github.com>2017-03-06 21:43:58 -0500
commit3882bd543a860ca64a9639ecd46868d8f4ad858e (patch)
tree347ac8a43a26e68680f63d6741018dbbb611c733
parentecb7d4f8088f151f7c33756dd07b33ff55b0ab53 (diff)
parentcf0d8bcc34bacbe2828ae38377c837a15f0cac76 (diff)
downloadcbt-3882bd543a860ca64a9639ecd46868d8f4ad858e.tar.gz
cbt-3882bd543a860ca64a9639ecd46868d8f4ad858e.tar.bz2
cbt-3882bd543a860ca64a9639ecd46868d8f4ad858e.zip
Merge pull request #391 from cvogt/publish-improvements
Publish improvements
-rw-r--r--plugins/essentials/PublishDynamic.scala7
-rw-r--r--plugins/essentials/SnapshotVersion.scala7
-rw-r--r--plugins/sonatype-release/src/SonatypeRelease.scala2
-rw-r--r--plugins/sonatype-release/src/sonatype/SonatypeLib.scala6
-rw-r--r--stage1/Stage1Lib.scala22
-rw-r--r--stage1/cbt.scala2
-rw-r--r--stage1/resolver.scala8
-rw-r--r--stage2/BasicBuild.scala8
-rw-r--r--stage2/Lib.scala33
-rw-r--r--stage2/Publish.scala4
-rw-r--r--stage2/plugins/PublishToArtifactory.scala12
11 files changed, 65 insertions, 46 deletions
diff --git a/plugins/essentials/PublishDynamic.scala b/plugins/essentials/PublishDynamic.scala
deleted file mode 100644
index 966230d..0000000
--- a/plugins/essentials/PublishDynamic.scala
+++ /dev/null
@@ -1,7 +0,0 @@
-package cbt
-
-trait PublishDynamic extends Publish with DynamicOverrides{
- def snapshot = newBuild[PublishDynamic]{"""
- override def version = super.version ++ "-SNAPSHOT"
- """}
-}
diff --git a/plugins/essentials/SnapshotVersion.scala b/plugins/essentials/SnapshotVersion.scala
new file mode 100644
index 0000000..1f7eb23
--- /dev/null
+++ b/plugins/essentials/SnapshotVersion.scala
@@ -0,0 +1,7 @@
+package cbt
+
+trait SnapshotVersion extends ArtifactInfo with DynamicOverrides{
+ def snapshot = newBuild[SnapshotVersion]{"""
+ override def version = super.version ++ "-SNAPSHOT"
+ """}
+}
diff --git a/plugins/sonatype-release/src/SonatypeRelease.scala b/plugins/sonatype-release/src/SonatypeRelease.scala
index 5d908f9..57c27df 100644
--- a/plugins/sonatype-release/src/SonatypeRelease.scala
+++ b/plugins/sonatype-release/src/SonatypeRelease.scala
@@ -22,5 +22,5 @@ trait SonatypeRelease extends Publish{
def publishSonatype = sonatypeLib.publishSigned( publishedArtifacts, releaseFolder )
- override def publish = {super.publish; publishSonatype}
+ override def publish = super.publish ++ publishSonatype
}
diff --git a/plugins/sonatype-release/src/sonatype/SonatypeLib.scala b/plugins/sonatype-release/src/sonatype/SonatypeLib.scala
index 317c60f..08f7ee1 100644
--- a/plugins/sonatype-release/src/sonatype/SonatypeLib.scala
+++ b/plugins/sonatype-release/src/sonatype/SonatypeLib.scala
@@ -74,18 +74,20 @@ final case class SonatypeLib(
artifacts, new URL(deployURI ++ releaseFolder), Some(credentials)
)
- if (releaseFolder.endsWith("-SNAPSHOT")){
+ val urls = if (releaseFolder.endsWith("-SNAPSHOT")){
publish(snapshotsURI)
} else {
val profile = getStagingProfile
val repoId = createStagingRepo(profile)
- publish(
+ val urls = publish(
serviceURI ++ "/staging/deployByRepositoryId/" ++ repoId.string
)
finishRelease( getStagingRepoById(repoId), profile )
+ urls
}
System.err.println(lib.green("Successfully published to Sonatype!"))
+ urls
}
/*
diff --git a/stage1/Stage1Lib.scala b/stage1/Stage1Lib.scala
index f2f468c..91e63f1 100644
--- a/stage1/Stage1Lib.scala
+++ b/stage1/Stage1Lib.scala
@@ -56,18 +56,26 @@ class Stage1Lib( logger: Logger ) extends BaseLib{
def write(file: File, content: String, options: OpenOption*): File = Stage0Lib.write(file, content, options:_*)
+ def addHttpCredentials( connection: HttpURLConnection, credentials: String ): Unit = {
+ val encoding = new sun.misc.BASE64Encoder().encode(credentials.getBytes)
+ connection.setRequestProperty("Authorization", "Basic " ++ encoding)
+ }
+
def download(url: URL, target: File, sha1: Option[String], replace: Boolean = false): Boolean = {
if( target.exists && !replace ){
- logger.resolver(green("found ") ++ url.string)
+ logger.resolver(green("found ") ++ url.show)
true
} else {
val incomplete = ( target ++ ".incomplete" ).toPath;
val connection = Stage0Lib.openConnectionConsideringProxy(url)
+ Option(url.getUserInfo).filter(_ != "").foreach(
+ addHttpCredentials(connection,_)
+ )
if(connection.getResponseCode != HttpURLConnection.HTTP_OK){
- logger.resolver(blue("not found: ") ++ url.string)
+ logger.resolver(blue("not found: ") ++ url.show)
false
} else {
- System.err.println(blue("downloading ") ++ url.string)
+ System.err.println(blue("downloading ") ++ url.show)
logger.resolver(blue("to ") ++ target.string)
target.getParentFile.mkdirs
val stream = connection.getInputStream
@@ -226,7 +234,7 @@ class Stage1Lib( logger: Logger ) extends BaseLib{
zincDeps
.collect{ case d @
BoundMavenDependency(
- _, _, MavenDependency( "com.typesafe.sbt", "sbt-interface", _, Classifier.none), _
+ _, _, MavenDependency( "com.typesafe.sbt", "sbt-interface", _, Classifier.none, _), _
) => d
}
.headOption
@@ -237,7 +245,7 @@ class Stage1Lib( logger: Logger ) extends BaseLib{
zincDeps
.collect{ case d @
BoundMavenDependency(
- _, _, MavenDependency( "com.typesafe.sbt", "compiler-interface", _, Classifier.sources), _
+ _, _, MavenDependency( "com.typesafe.sbt", "compiler-interface", _, Classifier.sources, _), _
) => d
}
.headOption
@@ -358,10 +366,10 @@ ${sourceFiles.sorted.mkString(" \\\n")}
def ScalaDependency(
groupId: String, artifactId: String, version: String, classifier: Classifier = Classifier.none,
- scalaMajorVersion: String
+ scalaMajorVersion: String, verifyHash: Boolean = true
) =
MavenDependency(
- groupId, artifactId ++ "_" ++ scalaMajorVersion, version, classifier
+ groupId, artifactId ++ "_" ++ scalaMajorVersion, version, classifier, verifyHash
)
def cacheOnDisk[T]
diff --git a/stage1/cbt.scala b/stage1/cbt.scala
index d28789c..0305dd2 100644
--- a/stage1/cbt.scala
+++ b/stage1/cbt.scala
@@ -65,7 +65,7 @@ object `package`{
}
implicit class URLExtensionMethods( url: URL ){
def ++( s: String ): URL = new URL( url.toString ++ s )
- def string = url.toString
+ def show = "/[^/@]+@".r.replaceFirstIn( url.toString, "/" ) // remove credentials when showing url for security reasons
}
implicit class SeqExtensions[T](seq: Seq[T]){
def maxOption(implicit ev: Ordering[T]): Option[T] = try{ Some(seq.max) } catch {
diff --git a/stage1/resolver.scala b/stage1/resolver.scala
index ab3196a..6e7ec09 100644
--- a/stage1/resolver.scala
+++ b/stage1/resolver.scala
@@ -210,7 +210,7 @@ abstract class DependenciesProxy{
}
case class MavenDependency(
- groupId: String, artifactId: String, version: String, classifier: Classifier = Classifier.none
+ groupId: String, artifactId: String, version: String, classifier: Classifier = Classifier.none, verifyHash: Boolean = true
){
private[cbt] def serialize = groupId ++ ":" ++ artifactId ++ ":"++ version ++ classifier.name.map(":" ++ _).getOrElse("")
}
@@ -231,7 +231,7 @@ case class BoundMavenDependency(
case o: BoundMavenDependency => o.mavenDependency == mavenDependency && o.repositories == repositories
case _ => false
}
- val MavenDependency( groupId, artifactId, version, classifier ) = mavenDependency
+ val MavenDependency( groupId, artifactId, version, classifier, verifyHash ) = mavenDependency
assert(
Option(groupId).collect{
case BoundMavenDependency.ValidIdentifier(_) =>
@@ -283,8 +283,8 @@ case class BoundMavenDependency(
def jarSha1: String = taskCache[BoundMavenDependency]("jarSha1").memoize{ resolveHash("jar", true) }
def pomSha1: String = taskCache[BoundMavenDependency]("pomSha1").memoize{ resolveHash("pom", false) }
- def jar: File = taskCache[BoundMavenDependency]("jar").memoize{ resolve("jar", Some(jarSha1), true) }
- def pom: File = taskCache[BoundMavenDependency]("pom").memoize{ resolve("pom", Some(pomSha1), false) }
+ def jar: File = taskCache[BoundMavenDependency]("jar").memoize{ resolve("jar", if(verifyHash) Some(jarSha1) else None, true) }
+ def pom: File = taskCache[BoundMavenDependency]("pom").memoize{ resolve("pom", if(verifyHash) Some(pomSha1) else None, false) }
private def pomXml = {
logger.resolver( "Loading pom file: " ++ pom.string )
diff --git a/stage2/BasicBuild.scala b/stage2/BasicBuild.scala
index 910cd5e..f102d5c 100644
--- a/stage2/BasicBuild.scala
+++ b/stage2/BasicBuild.scala
@@ -102,7 +102,7 @@ trait BaseBuild extends BuildInterface with DependencyImplementation with Trigge
/** Absolute path names for all individual files found in sources directly or contained in directories. */
final def sourceFiles: Seq[File] = lib.sourceFiles(sources, sourceFileFilter)
final def nonEmptySourceFiles: Seq[File] =
- if(sourceFiles.nonEmpty) {
+ if(sourceFiles.isEmpty) {
throw new RuntimeException( "no source files found" )
} else sourceFiles
@@ -119,8 +119,8 @@ trait BaseBuild extends BuildInterface with DependencyImplementation with Trigge
def ScalaDependency(
groupId: String, artifactId: String, version: String, classifier: Classifier = Classifier.none,
- scalaVersion: String = scalaMajorVersion
- ) = lib.ScalaDependency( groupId, artifactId, version, classifier, scalaVersion )
+ scalaVersion: String = scalaMajorVersion, verifyHash: Boolean = true
+ ) = lib.ScalaDependency( groupId, artifactId, version, classifier, scalaVersion, verifyHash )
final def DirectoryDependency(path: File, pathToNestedBuild: String*) = cbt.DirectoryDependency(
context.copy( workingDirectory = path ),
@@ -320,5 +320,5 @@ trait BaseBuild extends BuildInterface with DependencyImplementation with Trigge
@deprecated("use the MultipleScalaVersions plugin instead","")
final def crossScalaVersionsArray = Array(scalaVersion)
- def publish: Unit = ()
+ def publish: Seq[URL] = Seq()
}
diff --git a/stage2/Lib.scala b/stage2/Lib.scala
index 50b7389..c95ee2a 100644
--- a/stage2/Lib.scala
+++ b/stage2/Lib.scala
@@ -144,13 +144,15 @@ final class Lib(val logger: Logger) extends Stage1Lib(logger){
}.reduceOption(_ && _).getOrElse( ExitCode.Failure )
}
- private def render[T]( obj: T ): String = {
+ private def render( obj: Any ): String = {
obj match {
case Some(s) => render(s)
case None => ""
+ case url: URL => url.show // to remove credentials
case d: Dependency => lib.usage(d.getClass, d.show())
case c: ClassPath => c.string
case ExitCode(int) => System.err.println(int); System.exit(int); ???
+ case s: Seq[_] => s.map(render).mkString("\n")
case _ => obj.toString
}
}
@@ -423,27 +425,26 @@ final class Lib(val logger: Logger) extends Stage1Lib(logger){
else items.map(projection)
}
- def publishUnsigned( sourceFiles: Seq[File], artifacts: Seq[File], url: URL, credentials: Option[String] = None ): Unit = {
- if(sourceFiles.nonEmpty){
- publish( artifacts, url, credentials )
- }
+ def publishUnsigned( artifacts: Seq[File], url: URL, credentials: Option[String] = None ): Seq[URL] = {
+ publish( artifacts, url, credentials )
}
- def publishLocal( artifacts: Seq[File], mavenCache: File, releaseFolder: String ): Unit = {
+ def publishLocal( artifacts: Seq[File], mavenCache: File, releaseFolder: String ): Seq[File] = {
val targetDir = mavenCache ++ releaseFolder.stripSuffix("/")
targetDir.mkdirs
- artifacts.foreach{ a =>
+ artifacts.map{ a =>
val target = targetDir ++ ("/" ++ a.getName)
System.err.println(blue("publishing ") ++ target.getPath)
Files.copy( a.toPath, target.toPath, StandardCopyOption.REPLACE_EXISTING )
+ target
}
}
- def publishSigned( artifacts: Seq[File], url: URL, credentials: Option[String] = None ): Unit = {
+ def publishSigned( artifacts: Seq[File], url: URL, credentials: Option[String] = None ): Seq[URL] = {
publish( artifacts ++ artifacts.map(sign), url, credentials )
}
- private def publish(artifacts: Seq[File], url: URL, credentials: Option[String]): Unit = {
+ private def publish(artifacts: Seq[File], url: URL, credentials: Option[String]): Seq[URL] = {
val files = artifacts.map(nameAndContents)
lazy val checksums = files.flatMap{
case (name, content) => Seq(
@@ -455,24 +456,19 @@ final class Lib(val logger: Logger) extends Stage1Lib(logger){
uploadAll(url, all, credentials)
}
- def uploadAll(url: URL, nameAndContents: Seq[(String, Array[Byte])], credentials: Option[String] = None ): Unit =
+ def uploadAll(url: URL, nameAndContents: Seq[(String, Array[Byte])], credentials: Option[String] = None ): Seq[URL] =
nameAndContents.map{ case(name, content) => upload(name, content, url, credentials ) }
- def upload(fileName: String, fileContents: Array[Byte], baseUrl: URL, credentials: Option[String] = None): Unit = {
+ def upload(fileName: String, fileContents: Array[Byte], baseUrl: URL, credentials: Option[String] = None): URL = {
import java.net._
import java.io._
val url = baseUrl ++ "/" ++ fileName
- System.err.println(blue("uploading ") ++ url.toString)
+ System.err.println(blue("uploading ") ++ url.show)
val httpCon = Stage0Lib.openConnectionConsideringProxy(url)
try{
httpCon.setDoOutput(true)
httpCon.setRequestMethod("PUT")
- credentials.foreach(
- c => {
- val encoding = new sun.misc.BASE64Encoder().encode(c.getBytes)
- httpCon.setRequestProperty("Authorization", "Basic " ++ encoding)
- }
- )
+ (credentials orElse Option(baseUrl.getUserInfo)).foreach(addHttpCredentials(httpCon,_))
httpCon.setRequestProperty("Content-Type", "application/binary")
httpCon.getOutputStream.write(
fileContents
@@ -481,6 +477,7 @@ final class Lib(val logger: Logger) extends Stage1Lib(logger){
} finally {
httpCon.disconnect
}
+ url
}
diff --git a/stage2/Publish.scala b/stage2/Publish.scala
index e80471f..18a4849 100644
--- a/stage2/Publish.scala
+++ b/stage2/Publish.scala
@@ -3,8 +3,8 @@ import java.io.File
import java.net.URL
import java.nio.file.Files.readAllBytes
-trait Publish extends PublishMaven // FIXME: delete
-trait PublishMaven extends PackageJars{
+trait Publish extends PublishLocal // FIXME: delete
+trait PublishLocal extends PackageJars{
def description: String
def url: URL
def developers: Seq[Developer]
diff --git a/stage2/plugins/PublishToArtifactory.scala b/stage2/plugins/PublishToArtifactory.scala
new file mode 100644
index 0000000..333a468
--- /dev/null
+++ b/stage2/plugins/PublishToArtifactory.scala
@@ -0,0 +1,12 @@
+package cbt
+import java.net._
+import java.io._
+trait PublishToArtifactory extends PublishLocal{
+ def Artifactory = cbt.Artifactory( lib, publishedArtifacts, releaseFolder )
+}
+case class Artifactory( lib: Lib, publishedArtifacts: Seq[File], releaseFolder: String ){
+ case class withURL( url: URL, credentials: Option[String] = None ){
+ def publishUnsigned = lib.publishUnsigned( publishedArtifacts, url ++ releaseFolder, credentials )
+ def publishSigned = lib.publishSigned( publishedArtifacts, url ++ releaseFolder, credentials )
+ }
+}