How do I add a Nexus resolver after local repository, but before the default repositories? - sbt

We have an internal Nexus repository that we use to publish artifacts to and also to cache external dependencies (from Maven Central, Typesafe, etc.)
I want to add the repository as a resolver in my SBT build, under the following restrictions:
The settings need to be part of the build declaration (either .sbt or .scala, but not in the "global" sbt settings
If a dependency exists in the local repository, it should be taken from there. I don't want to have to access the network to get all the dependencies for every build.
If a dependency doesn't exist locally, sbt should first try to get it from the Nexus repository before trying the external repositories.
I saw several similar questions here, but didn't find any solution that does exactly this. Specifically, the code I currently have is:
externalResolvers ~= { rs => nexusResolver +: rs }
But when I show externalResolvers the Nexus repo appears before the local one.

So far, I've come up with the following solution:
externalResolvers ~= { rs =>
val grouped = rs.groupBy(_.isInstanceOf[FileRepository])
val fileRepos = grouped(true)
val remoteRepos = grouped(false)
fileRepos ++ (nexusResolver +: remoteRepos)
}
It works, but is kinda dirty... If anyone has a "cleaner" solution, I'd love to hear it.

Related

Unable to build cordapp with accounts dependencies

I was able to build a cordapp using Accounts by following the steps at https://github.com/corda/accounts.
This cordapp was building and running until 03/16/2020, but since 03/20/2020 I am seeing errors in my CI builds because https://ci-artifactory.corda.r3cev.com/artifactory/corda-lib-dev/com/r3/corda/lib/accounts/accounts-contracts/1.0-RC04/accounts-contracts-1.0-RC04.jar cannot be accessed. I get a 409 response now, how can I resolve this?
{
"errors" : [ {
"status" : 409,
"message" : "The repository 'corda-lib-dev' rejected the resolution of an artifact 'corda-lib-dev:com/r3/corda/lib/accounts/accounts-contracts/1.0-RC04/accounts-contracts-1.0-RC04.jar' due to conflict in the snapshot release handling policy."
} ]
}
My build.gradle has
accounts_release_version = '1.0-RC04'
accounts_release_group = 'com.r3.corda.lib.accounts'
confidential_id_release_group = "com.r3.corda.lib.ci"
confidential_id_release_version = "1.0-RC03"
repositories {
maven { url 'http://ci-artifactory.corda.r3cev.com/artifactory/corda-lib-dev' }
maven { url 'http://ci-artifactory.corda.r3cev.com/artifactory/corda-lib' }
}
My local builds on my development environment work fine, I assume because I already have the jars in my .m2
Artifactory configuration has been changed to enforce separation between release and snapshot repositories. corda-lib-dev is a snapshot repo and CorDapp developers should not be developing against these.
Releases and release candidates will be available in corda-lib going forward.
Kindly use corda-lib, and develop again release 1.0.
The pom file with RC04 is set to return 409. I assume Corda's way to disallow use of RC04. May be RC03 is also the same. I just tried this today and saw the repository pom files.
Use "1.0" instead of "1.0-RC03"

How to publish an artifact with pom-packaging in SBT?

I have a multi-project build in SBT where some projects should aggregate dependencies and contain no code. So then clients could depend on these projects as a single dependency instead of directly depending on all of their aggregated dependencies. With Maven, this is a common pattern, e.g. when using Spring Boot.
In SBT, I figured I can suppress the generation of the empty artifacts by adding this setting to these projects:
packagedArtifacts := Classpaths.packaged(Seq(makePom)).value
However, the makePom task writes <packaging>jar</packaging> in the generated POM. But now that there is no JAR anymore, this should read <packaging>pom</packaging> instead.
How can I do this?
This question is a bit old, but I just came across the same issue and found a solution. The original answer does point to the right page where this info can be found, but here is an example. It uses the pomPostProcess setting to transform the generated POM right before it is written to disk. Essentially, we loop over all the XML nodes, looking for the element we care about and then rewrite it.
import scala.xml.{Node => XmlNode, NodeSeq => XmlNodeSeq, _}
import scala.xml.transform._
pomPostProcess := { node: XmlNode =>
val rule = new RewriteRule {
override def transform(n: XmlNode): XmlNodeSeq = n match {
case e: Elem if e != null && e.label == "packaging" =>
<packaging>pom</packaging>
case _ => n
}
}
new RuleTransformer(rule).transform(node).head
},
Maybe you could modify the result pom as described here: Modifying the generated POM
You can disable publishing the default artifacts of JAR, sources, and docs, then opt in explicitly to publishing the POM. sbt produces and publishes a POM only, with <packaging>pom</packaging>.
// This project has no sources, I want <packaging>pom</pom> with dependencies
lazy val bundle = project
.dependsOn(moduleA, moduleB)
.settings(
publishArtifact := false, // Disable jar, sources, docs
publishArtifact in makePom := true,
)
lazy val moduleA = project
lazy val moduleB = project
lazy val moduleC = project
Run sbt bundle/publishM2 to verify the POM in ~/.m2/repository.
I dare say this is almost intuitive, a rare moment of pleasant surprise with sbt 😅
I confirmed this with current sbt 1.3.9, and 1.0.1, the oldest launcher I happen to have installed on my machine.
The Artifacts page in the reference docs may be helpful, perhaps this trick should be added there.

Instalation of Intershop 7.9 failing on missing version for demo cartridges

I'm trying to install a demo shop of Intershop version 7.9 but i'm failing to get it working. When I run "gradlew deployServer" I'm getting an error on all dependencies of the first demo shop cartridge:
Could not resolve all dependencies for configuration ':app_sf_responsive:compile'.
Could not resolve com.intershop.business:ac_ecircle:.
Required by:
nl.test.testproject:app_sf_responsive:1.0.0-LOCAL
No version for module 'com.intershop.business:ac_ecircle' in project properties and no version declared in dependency. Consider adding a version or filter property to 'C:\projects\test7.9\projects\testproject\gradle.properties'
I have followed the complete Intershop manual Setup CI Infrastructure but there is one point I don't know exactly what to do, that's with the new versioning plugin.
It is in chapter 6.2.5, any one have an idea how to configure that?
After loads of tinkering and mails back and forth with Intershop support I found a solution.
My alterations are in section 7.2.4 of the Setup CI Infrastructure of Intershop:
https://support.intershop.com/kb/index.php/Display/279D85#Cookbook-SetupCIInfrastructure-CorporateArtifactsRecipe:SetupCIBuildforCorporateArtifacts
I Made sure the corporate distribution is unique since I have more that 1 Intershop installation. Otherwise the upload to Nexus(in my case) will still fail.
In the build.gradle of the corporate distibution folder added disableSCM = true in the scm.version section. It now looks like this:
scm {
version {
type = 'threeDigits'
increment = 'MAJOR'
patternDigits = 1
disableSCM = true
initialVersion = '2.0.0'
}
}
If this is not added I got a bad request httpstatus 400 from Nexus because it tried to upload it as a snapshot while the distribution repository is a release repository.
Another problem is the distributionURL in the project/gradle/wrapper/gradle-wrapper.properties
All Nexus repository URL's are build up with < repoBaseURL > + repositories/snapshots, but the distributionURL is missing the repositories part.
After applied those changes it worked for me.

Remove local Git repo when working with JGit

I am building a small tool to propose some Git commands to users not familiar with Git. The commands are not intended to modify the repo, just consult some information.
I am creating the tool in Java, using JGit which seems to be the best match to do this kind of stuff.
The issue I face so far is that I create a temporary folder to host the repo content, but I am unable to delete it automatically at the end of the execution.
Here is the code (I removed the try/catch stuff to simplify the reading):
// Create temporary folder
Path folderPath = Paths.get(System.getProperty("user.dir"));
File localRepoFolder = Files.createTempDirectory(folderPath, "local-repo").toFile();
// Clone the repo
CloneCommand clone = new CloneCommand();
clone.setURI("https://myrepo");
clone.setNoCheckout(true);
clone.setDirectory(localRepoFolder);
clone.setCredentialsProvider(new UsernamePasswordCredentialsProvider("user", "password"));
Git gitRepo = clone.call();
// Do some stuff
[...]
// Cleanup before closing
gitRepo.getRepository().close();
gitRepo.close();
localRepoFolder.deleteOnExit();
I searched quite a lot on this topic, but I get everywhere that it should be automatically deleted... Am I missing something?
I would use something like Apache Commons IO (http://commons.apache.org/proper/commons-io/) which has a FileUtils.deleteDirectory

ivy.xml based sbt publish

There are 2 questions,
I defined publishTo with a resolver "abc", which is not in the external ivysettings.xml. When I do the publish, sbt complains resolver "abc" is undefined.
I defined an artifact, which is a zipped package, to be published, and the corresponding settings are as follows,
val ZIP = Configurations.config("app")
val artifact = SettingKey[Artifact]("artifact")
val pack = TaskKey[File]("pack")
val settings = Seq(artifact := Artifact(name.value, "zip", "zip", Some("app"), List(ZIP), None)) ++ addArtifact(artifact, pack).settings
It works pretty well when dependencies are managed by sbt itself, but totally cannot work (meaning the local publish just ignores publish of this artifact) if they are managed by ivy. How can I get over these?
Seems like the custom artifact settings does not work only if they are imported with an auto plugin, is it a bug or am I missing something?
thanks to this post:
How can a default task be overridden from an AutoPlugin?
so the artifacts settings must be introduced after sbt's own plugins are imported, otherwise it'd be overwritten.

Resources