From 03dc3f6fd04f74acc25c6b465a2e76584bca94da Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Sun, 22 Feb 2015 00:38:01 +0000 Subject: [PATCH 1/8] Disable publishing artificial root. --- main/src/main/scala/sbt/Build.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/src/main/scala/sbt/Build.scala b/main/src/main/scala/sbt/Build.scala index 6fd43bda0..b5f41a342 100644 --- a/main/src/main/scala/sbt/Build.scala +++ b/main/src/main/scala/sbt/Build.scala @@ -58,7 +58,7 @@ object Build { autoGeneratedProject := true ) def defaultAggregatedProject(id: String, base: File, agg: Seq[ProjectRef]): Project = - defaultProject(id, base).aggregate(agg: _*) + defaultProject(id, base).aggregate(agg: _*).settings(Keys.publishArtifact := false) @deprecated("Use Attributed.data", "0.13.0") def data[T](in: Seq[Attributed[T]]): Seq[T] = Attributed.data(in) From 58a2e634e21809f924421ae7551ae4c9b0c3f6ce Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Sun, 22 Feb 2015 04:15:11 +0000 Subject: [PATCH 2/8] Improve disabling publish artificial root. Not only is this safer, it also disables delivering the ivy file. --- main/src/main/scala/sbt/Build.scala | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/main/src/main/scala/sbt/Build.scala b/main/src/main/scala/sbt/Build.scala index b5f41a342..b61e0fb03 100644 --- a/main/src/main/scala/sbt/Build.scala +++ b/main/src/main/scala/sbt/Build.scala @@ -58,7 +58,10 @@ object Build { autoGeneratedProject := true ) def defaultAggregatedProject(id: String, base: File, agg: Seq[ProjectRef]): Project = - defaultProject(id, base).aggregate(agg: _*).settings(Keys.publishArtifact := false) + defaultProject(id, base).aggregate(agg: _*).settings( + Keys.publish := (), + Keys.publishLocal := () + ) @deprecated("Use Attributed.data", "0.13.0") def data[T](in: Seq[Attributed[T]]): Seq[T] = Attributed.data(in) From a770b9818f886ab24c2c910dc1a01bf255f44358 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Sun, 22 Feb 2015 04:17:11 +0000 Subject: [PATCH 3/8] Test that artificial root isn't published. --- .../project/artificial-root-no-publish/build.sbt | 10 ++++++++++ .../sbt-test/project/artificial-root-no-publish/test | 4 ++++ 2 files changed, 14 insertions(+) create mode 100644 sbt/src/sbt-test/project/artificial-root-no-publish/build.sbt create mode 100644 sbt/src/sbt-test/project/artificial-root-no-publish/test diff --git a/sbt/src/sbt-test/project/artificial-root-no-publish/build.sbt b/sbt/src/sbt-test/project/artificial-root-no-publish/build.sbt new file mode 100644 index 000000000..974a291a9 --- /dev/null +++ b/sbt/src/sbt-test/project/artificial-root-no-publish/build.sbt @@ -0,0 +1,10 @@ +val commonSettings = Seq( + organization := "com.example", + version := "0.1.0", + ivyPaths := new IvyPaths((baseDirectory in LocalRootProject).value, Some((target in LocalRootProject).value / "ivy-cache")) +) + +lazy val app = (project in file("app")). + settings(commonSettings: _*) + +commonSettings diff --git a/sbt/src/sbt-test/project/artificial-root-no-publish/test b/sbt/src/sbt-test/project/artificial-root-no-publish/test new file mode 100644 index 000000000..13d050bce --- /dev/null +++ b/sbt/src/sbt-test/project/artificial-root-no-publish/test @@ -0,0 +1,4 @@ +> publishLocal +$ exists target/ivy-cache/local/com.example/app_2.10/0.1.0/poms/app_2.10.pom +$ exists target/ivy-cache/local/com.example/app_2.10/0.1.0/jars/app_2.10.jar +$ absent target/ivy-cache/local/com.example/default-root_2.10/0.1.0/ivys/ivy.xml From f0732a8bd6ac969be16c11cc811123e094b51177 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Sun, 22 Feb 2015 04:23:19 +0000 Subject: [PATCH 4/8] Add a note for 1869/1871. --- notes/0.13.8.markdown | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/notes/0.13.8.markdown b/notes/0.13.8.markdown index c85da9dd7..f3a67c228 100644 --- a/notes/0.13.8.markdown +++ b/notes/0.13.8.markdown @@ -5,6 +5,7 @@ [@ajozwik]: https://github.com/ajozwik [@dwickern]: https://github.com/dwickern + [@dwijnand]: http://github.com/dwijnand [@Duhemm]: https://github.com/Duhemm [@kretes]: https://github.com/kretes [@indrajitr]: https://github.com/indrajitr @@ -38,6 +39,8 @@ [1787]: https://github.com/sbt/sbt/pull/1787 [1793]: https://github.com/sbt/sbt/pull/1793 [1817]: https://github.com/sbt/sbt/pull/1817 + [1869]: https://github.com/sbt/sbt/issues/1869 + [1871]: https://github.com/sbt/sbt/pull/1871 ### Changes with compatibility implications @@ -71,6 +74,7 @@ - Fixes eviction warning being too noisy. [#1615][1615] by [@eed3si9n][@eed3si9n] - Issues warning if multiple dependencies to a same library is found with different version. [#1634][1634] by [@eed3si9n][@eed3si9n] - Removes "No main class detected" warning. [#1766][1766] by [@eed3si9n][@eed3si9n] +- Disable publishing artificial root by default. [#1871][1871]/[#1869][1869] by [@dwijnand][@dwijnand] ### Rolling back XML parsing workaround From d07cdb92adac4f6accf9a036ece39fbb9381b2b5 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Sun, 22 Feb 2015 14:30:09 +0000 Subject: [PATCH 5/8] Make sure bare build.sbt is published by default. --- main/src/main/scala/sbt/Build.scala | 5 +---- main/src/main/scala/sbt/Load.scala | 4 +++- .../project/artificial-root-no-publish/changes/bare.sbt | 3 +++ sbt/src/sbt-test/project/artificial-root-no-publish/test | 6 ++++++ 4 files changed, 13 insertions(+), 5 deletions(-) create mode 100644 sbt/src/sbt-test/project/artificial-root-no-publish/changes/bare.sbt diff --git a/main/src/main/scala/sbt/Build.scala b/main/src/main/scala/sbt/Build.scala index b61e0fb03..6fd43bda0 100644 --- a/main/src/main/scala/sbt/Build.scala +++ b/main/src/main/scala/sbt/Build.scala @@ -58,10 +58,7 @@ object Build { autoGeneratedProject := true ) def defaultAggregatedProject(id: String, base: File, agg: Seq[ProjectRef]): Project = - defaultProject(id, base).aggregate(agg: _*).settings( - Keys.publish := (), - Keys.publishLocal := () - ) + defaultProject(id, base).aggregate(agg: _*) @deprecated("Use Attributed.data", "0.13.0") def data[T](in: Seq[Attributed[T]]): Seq[T] = Attributed.data(in) diff --git a/main/src/main/scala/sbt/Load.scala b/main/src/main/scala/sbt/Load.scala index b9dad65e3..0936f0dab 100755 --- a/main/src/main/scala/sbt/Load.scala +++ b/main/src/main/scala/sbt/Load.scala @@ -585,7 +585,9 @@ object Load { val existingIds = otherProjects.projects map (_.id) val refs = existingIds map (id => ProjectRef(buildUri, id)) val defaultID = autoID(buildBase, context, existingIds) - val root = finalizeProject(Build.defaultAggregatedProject(defaultID, buildBase, refs), files) + val root1 = Build.defaultAggregatedProject(defaultID, buildBase, refs) + val root2 = if (discovered.isEmpty) root1 else root1.settings(Keys.publish := (()), Keys.publishLocal := (())) + val root = finalizeProject(root2, files) val result = root +: (acc ++ otherProjects.projects) log.debug(s"[Loading] Done in ${buildBase}, returning: ${result.map(_.id).mkString("(", ", ", ")")}") LoadedProjects(result, generated ++ otherGenerated ++ generatedConfigClassFiles) diff --git a/sbt/src/sbt-test/project/artificial-root-no-publish/changes/bare.sbt b/sbt/src/sbt-test/project/artificial-root-no-publish/changes/bare.sbt new file mode 100644 index 000000000..936367950 --- /dev/null +++ b/sbt/src/sbt-test/project/artificial-root-no-publish/changes/bare.sbt @@ -0,0 +1,3 @@ +organization := "com.example" +version := "0.1.0" +ivyPaths := new IvyPaths((baseDirectory in LocalRootProject).value, Some((target in LocalRootProject).value / "ivy-cache")) diff --git a/sbt/src/sbt-test/project/artificial-root-no-publish/test b/sbt/src/sbt-test/project/artificial-root-no-publish/test index 13d050bce..3dda7dfd7 100644 --- a/sbt/src/sbt-test/project/artificial-root-no-publish/test +++ b/sbt/src/sbt-test/project/artificial-root-no-publish/test @@ -2,3 +2,9 @@ $ exists target/ivy-cache/local/com.example/app_2.10/0.1.0/poms/app_2.10.pom $ exists target/ivy-cache/local/com.example/app_2.10/0.1.0/jars/app_2.10.jar $ absent target/ivy-cache/local/com.example/default-root_2.10/0.1.0/ivys/ivy.xml + +$ copy-file changes/bare.sbt build.sbt +> reload +> publishLocal +$ exists target/ivy-cache/local/com.example/artificial-root-no-publish_2.10/0.1.0/poms/artificial-root-no-publish_2.10.pom +$ exists target/ivy-cache/local/com.example/artificial-root-no-publish_2.10/0.1.0/jars/artificial-root-no-publish_2.10.jar From 162ed3f3208fd2236dd03a49cf4aefd0b2e996d8 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 24 Feb 2015 22:46:11 -0500 Subject: [PATCH 6/8] Fixes #1869, Ref #1871. Don't enable IvyPlugin for multi project generated root --- main/src/main/scala/sbt/Build.scala | 10 +++++++--- main/src/main/scala/sbt/BuildStructure.scala | 13 +++++++++++++ main/src/main/scala/sbt/Load.scala | 8 ++++---- main/src/main/scala/sbt/Project.scala | 9 +++++++++ notes/0.13.8.markdown | 2 +- 5 files changed, 34 insertions(+), 8 deletions(-) diff --git a/main/src/main/scala/sbt/Build.scala b/main/src/main/scala/sbt/Build.scala index 6fd43bda0..b44735843 100644 --- a/main/src/main/scala/sbt/Build.scala +++ b/main/src/main/scala/sbt/Build.scala @@ -45,7 +45,13 @@ object Build { def defaultID(base: File, prefix: String = "default"): String = prefix + "-" + Hash.trimHashString(base.getAbsolutePath, 6) @deprecated("Explicitly specify the ID", "0.13.0") def defaultProject(base: File): Project = defaultProject(defaultID(base), base) - def defaultProject(id: String, base: File): Project = Project(id, base).settings( + def defaultProject(id: String, base: File): Project = Project(id, base).settings(defaultProjectSettings: _*) + def defaultAggregatedProject(id: String, base: File, agg: Seq[ProjectRef]): Project = + defaultProject(id, base).aggregate(agg: _*) + + private[sbt] def generatedRootWithoutIvyPlugin(id: String, base: File, agg: Seq[ProjectRef]): Project = + Project.mkGeneratedRoot(id, base, agg).settings(defaultProjectSettings: _*) + private[sbt] def defaultProjectSettings: Seq[Setting[_]] = Seq( // TODO - Can we move this somewhere else? ordering of settings is causing this to get borked. // if the user has overridden the name, use the normal organization that is derived from the name. organization := { @@ -57,8 +63,6 @@ object Build { }, autoGeneratedProject := true ) - def defaultAggregatedProject(id: String, base: File, agg: Seq[ProjectRef]): Project = - defaultProject(id, base).aggregate(agg: _*) @deprecated("Use Attributed.data", "0.13.0") def data[T](in: Seq[Attributed[T]]): Seq[T] = Attributed.data(in) diff --git a/main/src/main/scala/sbt/BuildStructure.scala b/main/src/main/scala/sbt/BuildStructure.scala index 30dfcf4e2..a06fe97a3 100644 --- a/main/src/main/scala/sbt/BuildStructure.scala +++ b/main/src/main/scala/sbt/BuildStructure.scala @@ -135,8 +135,21 @@ final class DetectedPlugins(val plugins: DetectedModules[Plugin], val autoPlugin }.partition(nonTopLevelPlugin) /** A function to select the right [[AutoPlugin]]s from [[autoPlugins]] for a [[Project]]. */ + @deprecated("Use deducePluginsFromProject", "0.13.8") lazy val deducePlugins: (Plugins, Logger) => Seq[AutoPlugin] = Plugins.deducer(autoPlugins.toList map { _.value }) + /** Selects the right [[AutoPlugin]]s from a [[Project]]. */ + def deducePluginsFromProject(p: Project, log: Logger): Seq[AutoPlugin] = + { + val ps0 = p.plugins + val allDetected = autoPlugins.toList map { _.value } + val detected = p match { + case _: GeneratedRootProject => allDetected filterNot { _ == sbt.plugins.IvyPlugin } + case _ => allDetected + } + Plugins.deducer(detected)(ps0, log) + } + private[this] def autoImports(pluginNames: Seq[String]) = pluginNames.map(_ + ".autoImport") private[this] def nonTopLevelPlugin(name: String) = name.contains('.') diff --git a/main/src/main/scala/sbt/Load.scala b/main/src/main/scala/sbt/Load.scala index 0936f0dab..8612ddc57 100755 --- a/main/src/main/scala/sbt/Load.scala +++ b/main/src/main/scala/sbt/Load.scala @@ -585,9 +585,9 @@ object Load { val existingIds = otherProjects.projects map (_.id) val refs = existingIds map (id => ProjectRef(buildUri, id)) val defaultID = autoID(buildBase, context, existingIds) - val root1 = Build.defaultAggregatedProject(defaultID, buildBase, refs) - val root2 = if (discovered.isEmpty) root1 else root1.settings(Keys.publish := (()), Keys.publishLocal := (())) - val root = finalizeProject(root2, files) + val root0 = if (discovered.isEmpty) Build.defaultAggregatedProject(defaultID, buildBase, refs) + else Build.generatedRootWithoutIvyPlugin(defaultID, buildBase, refs) + val root = finalizeProject(root0, files) val result = root +: (acc ++ otherProjects.projects) log.debug(s"[Loading] Done in ${buildBase}, returning: ${result.map(_.id).mkString("(", ", ", ")")}") LoadedProjects(result, generated ++ otherGenerated ++ generatedConfigClassFiles) @@ -647,7 +647,7 @@ object Load { } // 2. Discover all the autoplugins and contributed configurations. val autoPlugins = - try loadedPlugins.detected.deducePlugins(transformedProject.plugins, log) + try loadedPlugins.detected.deducePluginsFromProject(transformedProject, log) catch { case e: AutoPluginException => throw translateAutoPluginException(e, transformedProject) } val autoConfigs = autoPlugins.flatMap(_.projectConfigurations) diff --git a/main/src/main/scala/sbt/Project.scala b/main/src/main/scala/sbt/Project.scala index 3221ea101..152a18bfc 100755 --- a/main/src/main/scala/sbt/Project.scala +++ b/main/src/main/scala/sbt/Project.scala @@ -234,6 +234,13 @@ object Project extends ProjectExtra { auto: AddSettings = AddSettings.allDefaults): Project = unresolved(id, base, aggregate, dependencies, delegates, settings, configurations, auto, Plugins.empty, Nil) // Note: JvmModule/IvyModule auto included... + /** This is a variation of def apply that mixes in */ + private[sbt] def mkGeneratedRoot(id: String, base: File, aggregate: => Seq[ProjectReference]): Project = + { + validProjectID(id).foreach(errMsg => sys.error("Invalid project ID: " + errMsg)) + new ProjectDef[ProjectReference](id, base, aggregate, Nil, Nil, Nil, Nil, AddSettings.allDefaults, Plugins.empty, Nil) with Project with GeneratedRootProject + } + /** Returns None if `id` is a valid Project ID or Some containing the parser error message if it is not.*/ def validProjectID(id: String): Option[String] = DefaultParsers.parse(id, DefaultParsers.ID).left.toOption private[this] def validProjectIDStart(id: String): Boolean = DefaultParsers.parse(id, DefaultParsers.IDStart).isRight @@ -571,6 +578,8 @@ object Project extends ProjectExtra { } } +private[sbt] trait GeneratedRootProject + trait ProjectExtra { implicit def configDependencyConstructor[T <% ProjectReference](p: T): Constructor = new Constructor(p) implicit def classpathDependency[T <% ProjectReference](p: T): ClasspathDependency = new ClasspathDependency(p, None) diff --git a/notes/0.13.8.markdown b/notes/0.13.8.markdown index f3a67c228..e850dc14a 100644 --- a/notes/0.13.8.markdown +++ b/notes/0.13.8.markdown @@ -74,7 +74,7 @@ - Fixes eviction warning being too noisy. [#1615][1615] by [@eed3si9n][@eed3si9n] - Issues warning if multiple dependencies to a same library is found with different version. [#1634][1634] by [@eed3si9n][@eed3si9n] - Removes "No main class detected" warning. [#1766][1766] by [@eed3si9n][@eed3si9n] -- Disable publishing artificial root by default. [#1871][1871]/[#1869][1869] by [@dwijnand][@dwijnand] +- Disable publishing on implicitly created root project by not enabling `IvyPlugin` by default. [#1871][1871]/[#1869][1869] by [@dwijnand][@dwijnand] ### Rolling back XML parsing workaround From 30ca290a132e48066c1f13ed3795c8d7c162dc6d Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 25 Feb 2015 00:22:26 -0500 Subject: [PATCH 7/8] Add sbt.root.ivyplugin escape hatch --- main/src/main/scala/sbt/Load.scala | 2 +- notes/0.13.8.markdown | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/main/src/main/scala/sbt/Load.scala b/main/src/main/scala/sbt/Load.scala index 8612ddc57..764c8a73a 100755 --- a/main/src/main/scala/sbt/Load.scala +++ b/main/src/main/scala/sbt/Load.scala @@ -585,7 +585,7 @@ object Load { val existingIds = otherProjects.projects map (_.id) val refs = existingIds map (id => ProjectRef(buildUri, id)) val defaultID = autoID(buildBase, context, existingIds) - val root0 = if (discovered.isEmpty) Build.defaultAggregatedProject(defaultID, buildBase, refs) + val root0 = if (discovered.isEmpty || java.lang.Boolean.getBoolean("sbt.root.ivyplugin")) Build.defaultAggregatedProject(defaultID, buildBase, refs) else Build.generatedRootWithoutIvyPlugin(defaultID, buildBase, refs) val root = finalizeProject(root0, files) val result = root +: (acc ++ otherProjects.projects) diff --git a/notes/0.13.8.markdown b/notes/0.13.8.markdown index e850dc14a..f35a9c981 100644 --- a/notes/0.13.8.markdown +++ b/notes/0.13.8.markdown @@ -74,7 +74,7 @@ - Fixes eviction warning being too noisy. [#1615][1615] by [@eed3si9n][@eed3si9n] - Issues warning if multiple dependencies to a same library is found with different version. [#1634][1634] by [@eed3si9n][@eed3si9n] - Removes "No main class detected" warning. [#1766][1766] by [@eed3si9n][@eed3si9n] -- Disable publishing on implicitly created root project by not enabling `IvyPlugin` by default. [#1871][1871]/[#1869][1869] by [@dwijnand][@dwijnand] +- Disable publishing on implicitly created root project by not enabling `IvyPlugin` by default (`-Dsbt.root.ivyplugin=true` will revert this behavior). [#1871][1871]/[#1869][1869] by [@dwijnand][@dwijnand] ### Rolling back XML parsing workaround From b40a9e79c8d1f71bc7d433770771972cfddf6746 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 25 Feb 2015 00:43:58 -0500 Subject: [PATCH 8/8] Fixes per review --- main/src/main/scala/sbt/Project.scala | 2 +- .../build.sbt | 0 .../changes/bare.sbt | 0 .../test | 4 ++-- 4 files changed, 3 insertions(+), 3 deletions(-) rename sbt/src/sbt-test/project/{artificial-root-no-publish => generated-root-no-publish}/build.sbt (100%) rename sbt/src/sbt-test/project/{artificial-root-no-publish => generated-root-no-publish}/changes/bare.sbt (100%) rename sbt/src/sbt-test/project/{artificial-root-no-publish => generated-root-no-publish}/test (56%) diff --git a/main/src/main/scala/sbt/Project.scala b/main/src/main/scala/sbt/Project.scala index 152a18bfc..c6521271f 100755 --- a/main/src/main/scala/sbt/Project.scala +++ b/main/src/main/scala/sbt/Project.scala @@ -234,7 +234,7 @@ object Project extends ProjectExtra { auto: AddSettings = AddSettings.allDefaults): Project = unresolved(id, base, aggregate, dependencies, delegates, settings, configurations, auto, Plugins.empty, Nil) // Note: JvmModule/IvyModule auto included... - /** This is a variation of def apply that mixes in */ + /** This is a variation of def apply that mixes in GeneratedRootProject. */ private[sbt] def mkGeneratedRoot(id: String, base: File, aggregate: => Seq[ProjectReference]): Project = { validProjectID(id).foreach(errMsg => sys.error("Invalid project ID: " + errMsg)) diff --git a/sbt/src/sbt-test/project/artificial-root-no-publish/build.sbt b/sbt/src/sbt-test/project/generated-root-no-publish/build.sbt similarity index 100% rename from sbt/src/sbt-test/project/artificial-root-no-publish/build.sbt rename to sbt/src/sbt-test/project/generated-root-no-publish/build.sbt diff --git a/sbt/src/sbt-test/project/artificial-root-no-publish/changes/bare.sbt b/sbt/src/sbt-test/project/generated-root-no-publish/changes/bare.sbt similarity index 100% rename from sbt/src/sbt-test/project/artificial-root-no-publish/changes/bare.sbt rename to sbt/src/sbt-test/project/generated-root-no-publish/changes/bare.sbt diff --git a/sbt/src/sbt-test/project/artificial-root-no-publish/test b/sbt/src/sbt-test/project/generated-root-no-publish/test similarity index 56% rename from sbt/src/sbt-test/project/artificial-root-no-publish/test rename to sbt/src/sbt-test/project/generated-root-no-publish/test index 3dda7dfd7..3cfdd4401 100644 --- a/sbt/src/sbt-test/project/artificial-root-no-publish/test +++ b/sbt/src/sbt-test/project/generated-root-no-publish/test @@ -6,5 +6,5 @@ $ absent target/ivy-cache/local/com.example/default-root_2.10/0.1.0/ivys/ivy.xml $ copy-file changes/bare.sbt build.sbt > reload > publishLocal -$ exists target/ivy-cache/local/com.example/artificial-root-no-publish_2.10/0.1.0/poms/artificial-root-no-publish_2.10.pom -$ exists target/ivy-cache/local/com.example/artificial-root-no-publish_2.10/0.1.0/jars/artificial-root-no-publish_2.10.jar +$ exists target/ivy-cache/local/com.example/generated-root-no-publish_2.10/0.1.0/poms/generated-root-no-publish_2.10.pom +$ exists target/ivy-cache/local/com.example/generated-root-no-publish_2.10/0.1.0/jars/generated-root-no-publish_2.10.jar