3
votes

Has anyone published an sbt-native-packager produced artifact (tgz in my case) using sbt-aether-deploy to a nexus repo? (I need this for the timestamped snapshots, specifically the "correct" version tag in nexus' artifact-resolution REST resource).

I can do one or the other but can't figure out how to add the packagedArtifacts in Universal to the artifacts that sbt-aether-deploy deploys to do both.

I suspect the path to pursue would be to the addArtifact() the packagedArtifacts in Universal or creating another AetherArtifact and then to override/replace the deployTask to use that AetherArtifact?

Any help much appreciated.

3

3 Answers

2
votes

I am the author of the sbt-aether-deploy plugin, and I just came over this post.

import aether.AetherKeys._

crossPaths := false //needed if you want to remove the scala version from the artifact name

enablePlugins(JavaAppPackaging)

aetherArtifact := {
    val artifact = aetherArtifact.value
    artifact.attach((packageBin in Universal).value, "dist", "zip")
}

This will also publish the other main artifact.

If you want to disable publishing of the main artifact, then you will need to rewrite the artifact coordinates. Maven requires a main artifact.

I have added a way to replace the main artifact for this purpose, but I can now see that way is kind of flawed. It will still assume that the artifact is published as a jar file. The main artifact type is locked down to that, since the POM packaging is set to jar by default by SBT.

If this is an app, then that limitation is probably OK, since Maven will never resolve that into an artifact.

The "proper" way in Maven terms is to add a classifier to the artifact and change the "packaging" in the POM file to "pom". We will see if I get around to changing that particular part.

1
votes

Ok, I think I got it amazingly enough. If there's a better way to do it I'd love to hear. Not loving that blind Option.get there..

  val tgzCoordinates = SettingKey[MavenCoordinates]("the maven coordinates for the tgz")

  lazy val myPackagerSettings = packageArchetype.java_application ++ deploymentSettings ++   Seq(
    publish <<= publish.dependsOn(publish in Universal),
    publishLocal <<= publishLocal.dependsOn(publishLocal in Universal)
  )

  lazy val defaultSettings = buildSettings ++ Publish.settings ++  Seq(
    scalacOptions in Compile ++= Seq("-encoding", "UTF-8", "-target:jvm-1.7", "-deprecation", "-feature", "-unchecked", "-Xlog-reflective-calls"),
    testOptions in Test += Tests.Argument("-oDF")
  )

  lazy val myAetherSettings = aetherSettings ++ aetherPublishBothSettings

  lazy val toastyphoenixProject = Project(
    id = "toastyphoenix",
    base = file("."),
    settings = defaultSettings ++ myPackagerSettings ++ myAetherSettings ++ Seq(
      name in Universal := name.value + "_" + scalaBinaryVersion.value,
      packagedArtifacts in Universal ~= { _.filterNot { case (artifact, file) => artifact.`type`.contains("zip")}},
      libraryDependencies ++= Dependencies.phoenix,
      tgzCoordinates := MavenCoordinates(organization.value + ":" + (name in Universal).value + ":tgz:" + version.value).get,
      aetherArtifact <<= (tgzCoordinates, packageZipTarball in Universal, makePom in Compile, packagedArtifacts in Universal) map {
        (coords: MavenCoordinates, mainArtifact: File, pom: File, artifacts: Map[Artifact, File]) =>
          createArtifact(artifacts, pom, coords, mainArtifact)
      }
    )
  )
1
votes

I took Peter's solution and reworked it slightly, avoiding the naked Option.get by creating the MavenCoordinates directly:

import aether.MavenCoordinates
import aether.Aether.createArtifact

name := "mrb-test"

organization := "me.mbarton"

version := "1.0"

crossPaths := false

packageArchetype.java_application

publish <<= (publish) dependsOn (publish in Universal)

publishLocal <<= (publishLocal) dependsOn (publishLocal in Universal)

aetherPublishBothSettings

aetherArtifact <<= (organization, name in Universal, version, packageBin in Universal, makePom in Compile, packagedArtifacts in Universal) map {
    (organization, name, version, binary, pom, artifacts) =>
        val nameWithoutVersion = name.replace(s"-$version", "")
        createArtifact(artifacts, pom, MavenCoordinates(organization, nameWithoutVersion, version, None, "zip"), binary)
}

The nameWithoutVersion replace works around SBT native packager including the version in the artifact name:

  • Before: me/mbarton/mrb-test-1.0/1.0/mrb-test-1.0.zip
  • After: me/mbarton/mrb-test/1.0/mrb-test-1.0.zip

crossPaths avoids the Scala postfix on the version.