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

Clarify (fix?) aggregation

Open keynmol opened this issue 4 years ago • 3 comments

At the moment the aggregation works differently for project matrices.

// cat build.sbt
lazy val root = projectMatrix.in(file(".")).aggregate(core, api).settings(commons)


lazy val core = projectMatrix.in(file("core")).jvmPlatform(scalaVersions = Seq("2.13.6")).settings(commons)
lazy val api = projectMatrix.in(file("api")).jvmPlatform(scalaVersions = Seq("2.13.6")).settings(commons)

val commons = Seq(
  publishTo := Some("Nexus" at "http://big-scary-corp.com")
)

// project/plugins.sbt
addSbtPlugin("com.eed3si9n" % "sbt-projectmatrix" % "0.8.0")

// $ sbt 'show publishTo'
[info] welcome to sbt 1.5.5 (AdoptOpenJDK Java 11.0.11)
[info] loading global plugins from /.../.sbt/1.0/plugins
[info] loading settings for project tmp-tdxyj8ux-build from plugins.sbt ...
[info] loading project definition from /private/var/folders/m1/3py6pkgs3l1dvt3jpdht11nc0000gn/T/tmp.TDXYj8Ux/project
[info] loading settings for project tmp-tdxyj8ux from build.sbt ...
[info] set current project to tmp-tdxyj8ux (in build file:/private/var/folders/m1/3py6pkgs3l1dvt3jpdht11nc0000gn/T/tmp.TDXYj8Ux/)
[info] core / publishTo
[info] 	Some(Nexus: http://big-scary-corp.com)
[info] api / publishTo
[info] 	Some(Nexus: http://big-scary-corp.com)
[info] publishTo
[info] 	None
[success] Total time: 0 s, completed 13 Oct 2021, 13:28:54

The most common situation I've seen this become a problem is running sbt publish and aggregated project failing with Repository for publishing is not specified.

workaround

To circumvent it, one must go a different route:

diff --git a/build.sbt.old b/build.sbt
index 29f0ee1..564b84a 100644
--- a/build.sbt.old
+++ b/build.sbt
@@ -1,4 +1,4 @@
-lazy val root = projectMatrix.in(file(".")).aggregate(core, api).settings(commons)
+lazy val root = project.in(file(".")).aggregate((core.projectRefs ++ api.projectRefs):_*).settings(commons)


 lazy val core = projectMatrix.in(file("core")).jvmPlatform(scalaVersions = Seq("2.13.6")).settings(commons)

Which behaves as you expect:

// $ sbt 'show publishTo'
[info] welcome to sbt 1.5.5 (AdoptOpenJDK Java 11.0.11)
[info] loading global plugins from /.../.sbt/1.0/plugins
[info] loading settings for project tmp-tdxyj8ux-build from plugins.sbt ...
[info] loading project definition from /private/var/folders/m1/3py6pkgs3l1dvt3jpdht11nc0000gn/T/tmp.TDXYj8Ux/project
[info] loading settings for project root from build.sbt ...
[info] set current project to root (in build file:/private/var/folders/m1/3py6pkgs3l1dvt3jpdht11nc0000gn/T/tmp.TDXYj8Ux/)
[info] core / publishTo
[info] 	Some(Nexus: http://big-scary-corp.com)
[info] api / publishTo
[info] 	Some(Nexus: http://big-scary-corp.com)
[info] publishTo
[info] 	Some(Nexus: http://big-scary-corp.com)
[success] Total time: 0 s, completed 13 Oct 2021, 13:33:12

With the downside of not being more verbose, of course

solution

TBD, I haven't looked at the code in detail yet to understand why this happens.

Suspect that this:

https://github.com/sbt/sbt-projectmatrix/blob/e46c2e3c3a4eba186a204303834e5d01893455b7/src/main/scala/sbt/internal/ProjectMatrix.scala#L249-L250

is to blame.

Not sure what's the best way to solve this?

keynmol avatar Oct 13 '21 12:10 keynmol

Maybe you need to add publish / skip := true?

eed3si9n avatar Oct 13 '21 22:10 eed3si9n

Doesn't have effect, same with publish := {}.

In fact, if you look at the projects created:

[info] 	   api
[info] 	   core
[info] 	 * tmp-jrfolkaw

tmp-jrfolkaw - is the temp folder I run this in. Which means root was not created at all.

Which makes sense, because just calling aggregate doesn't create any rows, so the project is not registered at all (because it iterates over rows here).

At the same time, you can't really synthesise project rows for root project from aggregatees, right?

I think this needs to have 4 scenarios during projects generation:

  1. if rows is empty and aggregates is empty -> generate no projects
  2. if rows is non-empty and aggregates is non-empty -> generate project according to rows and each one aggregates other projects
  3. if rows is empty and aggregates is non-empty -> generate 1 project which just does aggregation, don't mangle the name of that project
  4. if rows is non-empty and aggregates is empty -> same as 2, without adding .aggregate to generated project

WDYT?

keynmol avatar Oct 14 '21 06:10 keynmol

  1. if rows is empty and aggregates is non-empty -> generate 1 project which just does aggregation, don't mangle the name of that project

I am not 100% sure, but I have a feeling that adding this inconsistency would end up making the design weaker. Maybe we could add some method that adds a dummy row?

eed3si9n avatar Oct 15 '21 02:10 eed3si9n