sbt-pack icon indicating copy to clipboard operation
sbt-pack copied to clipboard

Split out selection of all JARs into separate TaskKey

Open choffmeister opened this issue 10 years ago • 7 comments

I write a SBT plugin myself right now and need a list of all dependent JARs. For this I use sbt-pack since it does the job of finding and resolving all needed JARs very well. Sadly, the collecting of the JARs is done within the pack TaskKey. Wouldn't it be more useful, to create a separate TaskKey for that, maybe:

val packAllLibJars = TaskKey[Seq[File]]("pack-all-lib-jars", "all (compiled, dependent, managed, unmanaged) JARs needed")

This would help me and others to take advantage of your resolve strategy, and more important, lead to less code duplication (the loop do copy the individual JARs is duplicated three times) in sbt-pack itself.

choffmeister avatar Nov 05 '14 10:11 choffmeister

I started a plugin sbt-jars only for the purpose of gathering all JARs together. Much code I borrowed from here. As many plugins like this one and sbt-assembly for example need a list of JARs I think it would be useful, to outsource the gathering into a separate plugin that can be used by the others.

What do you think?

choffmeister avatar Nov 07 '14 14:11 choffmeister

Generally speaking, I really like the idea to have a common library that can be used from sbt-pack, sbt-assembly, etc.

In practice, however, sbt-pack is very tiny plugin, and for the maintainability its release process should not depend on the other projects.

For example, version number ordering strategy is often subjects to change (for example, if the user use 0.1-(git revision number) tag, we need to extend the ordering, but to modify this we need to update both of sbt-jars and sbt-pack and deploy them to sonatype. It doubles the operation cost.

Having packAllLibJars task in sbt-pack plugin is a nice idea. I prefer to add this task to sbt-pack.

Thanks.

xerial avatar Nov 08 '14 02:11 xerial

OK, I can understand that.

Your hint for version number ordering: Could it be the case, that sbt-pack currently just orders version strings lexicographically? Hence by now it is "2.10.4" < "2.9.2"? If I am right and if you like you can use (copy&paste) the VersionString class from sbt-jars that I wrote. There is a DefaultVersionStringOrdering implementation, that properly handles the following cases:

"properly sort" in {
  VersionString("1") must be_<(VersionString("1.2.3.4"))
  VersionString("2") must be_>(VersionString("1.2.3.4"))
  VersionString("1.2.2") must be_<(VersionString("1.2.3.4"))
  VersionString("1.2.4") must be_>(VersionString("1.2.3.4"))
  VersionString("1.2.3.4.5") must be_>(VersionString("1.2.3.4"))

  VersionString("2.9.2") must be_<(VersionString("2.10.4"))

  VersionString("1.2") must be_>(VersionString("1.2-alpha"))
  VersionString("1.2-beta") must be_>(VersionString("1.2-alpha"))

  VersionString("apple") must be_<(VersionString("pie"))
}

Edit: I have created a separate PR #50 for the version string issue.

choffmeister avatar Nov 10 '14 08:11 choffmeister

Regarding your concerns, that Version ordering is subject to change: In sbt-jars I resolved the issue by making the ordering itself configurable. The duplicate JAR strategy is represented by a sealed trait

sealed trait DuplicatedJarStrategy
object DuplicatedJarStrategies {
  case class Latest(ordering: Ordering[String]) extends DuplicatedJarStrategy
  case object Error extends DuplicatedJarStrategy
}

and hence allows to specify what "latest" actually means by specifying an Ordering[String]. The default strategy is (VersionString and DefaultVersionStringOrdering are the same classes as merged in with #50):

private val defaultVersionOrdering = new Ordering[String] {
  override def compare(a: String, b: String): Int = {
    DefaultVersionStringOrdering.compare(VersionString(a), VersionString(b))
  }
}

jarsDuplicatedStrategy := DuplicatedJarStrategies.Latest(defaultVersionOrdering)

Now per default version string ordering according to http://semver.org/ is used, but one can easily provide a custom implementation for the ordering.

choffmeister avatar Nov 12 '14 09:11 choffmeister

Great. So packDuplicateJarStrategy can be configurable with this strategy, instead of specifying a string (e.g., "latest")

xerial avatar Nov 12 '14 10:11 xerial

Exactly.

But this tweak is so far only available in sbt-jars. Just saying it here because I think it would also be a good thing for sbt-pack. The drawback would be, that updating sbt-pack with this would introduce a not backward compatible change (at least for those, who explicitly set the strategy to "error").

choffmeister avatar Nov 12 '14 10:11 choffmeister

For such an incompatible change, we can increase the minor version (e.g., 0.7.0) to notify the change.

xerial avatar Nov 12 '14 14:11 xerial