Skip to content

Commit b1cd484

Browse files
committed
refactor republishing to a plugin
1 parent 465da00 commit b1cd484

File tree

2 files changed

+144
-113
lines changed

2 files changed

+144
-113
lines changed

project/Build.scala

Lines changed: 7 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import pl.project13.scala.sbt.JmhPlugin
1212
import pl.project13.scala.sbt.JmhPlugin.JmhKeys.Jmh
1313
import sbt.Package.ManifestAttributes
1414
import sbt.PublishBinPlugin.autoImport._
15+
import dotty.tools.sbtplugin.RepublishPlugin
16+
import dotty.tools.sbtplugin.RepublishPlugin.autoImport._
1517
import sbt.plugins.SbtPlugin
1618
import sbt.ScriptedPlugin.autoImport._
1719
import xerial.sbt.pack.PackPlugin
@@ -2104,120 +2106,14 @@ object Build {
21042106
)
21052107
)
21062108

2107-
lazy val DistCacheConfig = config("DistCacheConfig") extend Compile
2108-
2109-
val distModules = taskKey[Seq[(ModuleID, Map[Artifact, File])]]("fetch local artifacts for distribution.")
2110-
val distResolvedArtifacts = taskKey[Seq[ResolvedArtifacts]]("Resolve the dependencies for the distribution")
2111-
val distCaching = taskKey[File]("cache the dependencies for the distribution")
2112-
2113-
def evalPublishSteps(dependencies: Seq[ProjectReference]): Def.Initialize[Task[Seq[(ModuleID, Map[Artifact, File])]]] = {
2114-
val publishAllLocalBin = dependencies.map({ d => ((d / publishLocalBin / packagedArtifacts)) }).join
2115-
val resolveId = dependencies.map({ d => ((d / projectID)) }).join
2116-
Def.task {
2117-
val s = streams.value
2118-
val log = s.log
2119-
val published = publishAllLocalBin.value
2120-
val ids = resolveId.value
2121-
2122-
ids.zip(published)
2123-
}
2124-
}
2125-
2126-
case class SimpleModuleId(org: String, name: String, revision: String) {
2127-
override def toString = s"$org:$name:$revision"
2128-
}
2129-
case class ResolvedArtifacts(id: SimpleModuleId, jar: File, pom: File)
2130-
2131-
def commonDistSettings(dependencies: Seq[ClasspathDep[ProjectReference]]) = Seq(
2109+
lazy val commonDistSettings = Seq(
21322110
packMain := Map(),
21332111
publishArtifact := false,
21342112
packGenerateMakefile := false,
21352113
packArchiveName := "scala3-" + dottyVersion,
2136-
DistCacheConfig / distModules := {
2137-
evalPublishSteps(dependencies.map(_.project)).value
2138-
},
2139-
DistCacheConfig / distResolvedArtifacts := {
2140-
val localArtifactIds = (DistCacheConfig / distModules).value
2141-
val report = (thisProjectRef / updateFull).value
2142-
2143-
val found = mutable.Map.empty[SimpleModuleId, ResolvedArtifacts]
2144-
val evicted = mutable.Set.empty[SimpleModuleId]
2145-
2146-
localArtifactIds.foreach({ case (id, as) =>
2147-
val simpleId = {
2148-
val name0 = id.crossVersion match {
2149-
case _: CrossVersion.Binary =>
2150-
// projectID does not add binary suffix
2151-
(id.name + "_3").ensuring(!id.name.endsWith("_3") && id.revision.startsWith("3."))
2152-
case _ => id.name
2153-
}
2154-
SimpleModuleId(id.organization, name0, id.revision)
2155-
}
2156-
var jarOrNull: File = null
2157-
var pomOrNull: File = null
2158-
as.foreach({ case (a, f) =>
2159-
if (a.`type` == "jar") {
2160-
jarOrNull = f
2161-
} else if (a.`type` == "pom") {
2162-
pomOrNull = f
2163-
}
2164-
})
2165-
assert(jarOrNull != null, s"Could not find jar for ${id}")
2166-
assert(pomOrNull != null, s"Could not find pom for ${id}")
2167-
evicted += simpleId.copy(revision = simpleId.revision + "-nonbootstrapped")
2168-
found(simpleId) = ResolvedArtifacts(simpleId, jarOrNull, pomOrNull)
2169-
})
2170-
2171-
report.allModuleReports.foreach { mr =>
2172-
val simpleId = {
2173-
val id = mr.module
2174-
SimpleModuleId(id.organization, id.name, id.revision)
2175-
}
2176-
2177-
if (!found.contains(simpleId) && !evicted(simpleId)) {
2178-
var jarOrNull: File = null
2179-
var pomOrNull: File = null
2180-
mr.artifacts.foreach({ case (a, f) =>
2181-
if (a.`type` == "jar" || a.`type` == "bundle") {
2182-
jarOrNull = f
2183-
} else if (a.`type` == "pom") {
2184-
pomOrNull = f
2185-
}
2186-
})
2187-
assert(jarOrNull != null, s"Could not find jar for ${simpleId}")
2188-
if (pomOrNull == null) {
2189-
val jarPath = jarOrNull.toPath
2190-
// we found the jar, so assume we can resolve a sibling pom file
2191-
val pomPath = jarPath.resolveSibling(jarPath.getFileName.toString.stripSuffix(".jar") + ".pom")
2192-
assert(Files.exists(pomPath), s"Could not find pom for ${simpleId}")
2193-
pomOrNull = pomPath.toFile
2194-
}
2195-
found(simpleId) = ResolvedArtifacts(simpleId, jarOrNull, pomOrNull)
2196-
}
2197-
2198-
}
2199-
found.values.toSeq
2200-
},
2201-
DistCacheConfig / distCaching := {
2202-
val resolved = (DistCacheConfig / distResolvedArtifacts).value
2203-
val targetDir = target.value
2204-
val cacheDir = targetDir / "local-repo"
2205-
val mavenRepo = cacheDir / "maven2"
2206-
IO.createDirectory(mavenRepo)
2207-
resolved.foreach { ra =>
2208-
val jar = ra.jar
2209-
val pom = ra.pom
2210-
2211-
val pathElems = ra.id.org.split('.').toVector :+ ra.id.name :+ ra.id.revision
2212-
val artifactDir = pathElems.foldLeft(mavenRepo)(_ / _)
2213-
IO.createDirectory(artifactDir)
2214-
IO.copyFile(jar, artifactDir / jar.getName)
2215-
IO.copyFile(pom, artifactDir / pom.getName)
2216-
}
2217-
cacheDir
2218-
},
2114+
republishRepo := target.value / "local-repo",
22192115
Compile / pack := {
2220-
val localRepo = (DistCacheConfig / distCaching).value
2116+
val localRepo = republishClasspath.value // republish all artifacts to local repo
22212117
(Compile / pack).value
22222118
}
22232119
)
@@ -2355,7 +2251,9 @@ object Build {
23552251

23562252
def asDist(implicit mode: Mode): Project = project.
23572253
enablePlugins(PackPlugin).
2254+
enablePlugins(RepublishPlugin).
23582255
withCommonSettings.
2256+
settings(commonDistSettings).
23592257
dependsOn(
23602258
`scala3-interfaces`,
23612259
dottyCompiler,
@@ -2366,14 +2264,10 @@ object Build {
23662264
scaladoc,
23672265
`scala3-sbt-bridge`, // for scala-cli
23682266
).
2369-
withDepSettings(commonDistSettings).
23702267
bootstrappedSettings(
23712268
target := baseDirectory.value / "target" // override setting in commonBootstrappedSettings
23722269
)
23732270

2374-
def withDepSettings(f: Seq[ClasspathDep[ProjectReference]] => Seq[Setting[?]]): Project =
2375-
project.settings(f(project.dependencies))
2376-
23772271
def withCommonSettings(implicit mode: Mode): Project = project.settings(mode match {
23782272
case NonBootstrapped => commonNonBootstrappedSettings
23792273
case Bootstrapped => commonBootstrappedSettings

project/RepublishPlugin.scala

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
package dotty.tools.sbtplugin
2+
3+
import sbt._
4+
import xerial.sbt.pack.PackPlugin
5+
import sbt.Keys._
6+
import sbt.AutoPlugin
7+
import sbt.PublishBinPlugin
8+
import sbt.PublishBinPlugin.autoImport._
9+
10+
import scala.collection.mutable
11+
import java.nio.file.Files
12+
13+
/** This local plugin provides ways of publishing a project classpath and library dependencies to
14+
* .a local repository */
15+
object RepublishPlugin extends AutoPlugin {
16+
override def trigger = allRequirements
17+
override def requires = super.requires && PublishBinPlugin && PackPlugin
18+
19+
object autoImport {
20+
val republishProjectRefs = taskKey[Seq[ProjectRef]]("fetch the classpath deps from the project.")
21+
val republishLocalResolved = taskKey[Seq[ResolvedArtifacts]]("resolve local artifacts for distribution.")
22+
val republishAllResolved = taskKey[Seq[ResolvedArtifacts]]("Resolve the dependencies for the distribution")
23+
val republishClasspath = taskKey[File]("cache the dependencies for the distribution")
24+
val republishRepo = settingKey[File]("the location to store the republished artifacts.")
25+
}
26+
27+
import autoImport._
28+
29+
case class SimpleModuleId(org: String, name: String, revision: String) {
30+
override def toString = s"$org:$name:$revision"
31+
}
32+
case class ResolvedArtifacts(id: SimpleModuleId, jar: File, pom: File)
33+
34+
override val projectSettings: Seq[Def.Setting[_]] = Def.settings(
35+
republishLocalResolved / republishProjectRefs := {
36+
val proj = thisProjectRef.value
37+
val deps = buildDependencies.value
38+
39+
deps.classpathRefs(proj)
40+
},
41+
republishLocalResolved := Def.taskDyn {
42+
val deps = (republishLocalResolved / republishProjectRefs).value
43+
val publishAllLocalBin = deps.map({ d => ((d / publishLocalBin / packagedArtifacts)) }).join
44+
val resolveId = deps.map({ d => ((d / projectID)) }).join
45+
Def.task {
46+
val s = streams.value
47+
val log = s.log
48+
val published = publishAllLocalBin.value
49+
val ids = resolveId.value
50+
51+
ids.zip(published).map({ case (id, as) =>
52+
val simpleId = {
53+
val name0 = id.crossVersion match {
54+
case _: CrossVersion.Binary =>
55+
// projectID does not add binary suffix
56+
(id.name + "_3").ensuring(!id.name.endsWith("_3") && id.revision.startsWith("3."))
57+
case _ => id.name
58+
}
59+
SimpleModuleId(id.organization, name0, id.revision)
60+
}
61+
var jarOrNull: File = null
62+
var pomOrNull: File = null
63+
as.foreach({ case (a, f) =>
64+
if (a.`type` == "jar") {
65+
jarOrNull = f
66+
} else if (a.`type` == "pom") {
67+
pomOrNull = f
68+
}
69+
})
70+
assert(jarOrNull != null, s"Could not find jar for ${id}")
71+
assert(pomOrNull != null, s"Could not find pom for ${id}")
72+
ResolvedArtifacts(simpleId, jarOrNull, pomOrNull)
73+
})
74+
}
75+
}.value,
76+
republishAllResolved := {
77+
val localResolved = republishLocalResolved.value
78+
val report = (thisProjectRef / updateFull).value
79+
80+
val found = mutable.Map.empty[SimpleModuleId, ResolvedArtifacts]
81+
val evicted = mutable.Set.empty[SimpleModuleId]
82+
83+
localResolved.foreach({ resolved =>
84+
val simpleId = resolved.id
85+
evicted += simpleId.copy(revision = simpleId.revision + "-nonbootstrapped")
86+
found(simpleId) = resolved
87+
})
88+
89+
report.allModuleReports.foreach { mr =>
90+
val simpleId = {
91+
val id = mr.module
92+
SimpleModuleId(id.organization, id.name, id.revision)
93+
}
94+
95+
if (!found.contains(simpleId) && !evicted(simpleId)) {
96+
var jarOrNull: File = null
97+
var pomOrNull: File = null
98+
mr.artifacts.foreach({ case (a, f) =>
99+
if (a.`type` == "jar" || a.`type` == "bundle") {
100+
jarOrNull = f
101+
} else if (a.`type` == "pom") {
102+
pomOrNull = f
103+
}
104+
})
105+
assert(jarOrNull != null, s"Could not find jar for ${simpleId}")
106+
if (pomOrNull == null) {
107+
val jarPath = jarOrNull.toPath
108+
// we found the jar, so assume we can resolve a sibling pom file
109+
val pomPath = jarPath.resolveSibling(jarPath.getFileName.toString.stripSuffix(".jar") + ".pom")
110+
assert(Files.exists(pomPath), s"Could not find pom for ${simpleId}")
111+
pomOrNull = pomPath.toFile
112+
}
113+
found(simpleId) = ResolvedArtifacts(simpleId, jarOrNull, pomOrNull)
114+
}
115+
116+
}
117+
found.values.toSeq
118+
},
119+
republishClasspath := {
120+
val resolved = republishAllResolved.value
121+
val cacheDir = republishRepo.value
122+
val mavenRepo = cacheDir / "maven2"
123+
IO.createDirectory(mavenRepo)
124+
resolved.foreach { ra =>
125+
val jar = ra.jar
126+
val pom = ra.pom
127+
128+
val pathElems = ra.id.org.split('.').toVector :+ ra.id.name :+ ra.id.revision
129+
val artifactDir = pathElems.foldLeft(mavenRepo)(_ / _)
130+
IO.createDirectory(artifactDir)
131+
IO.copyFile(jar, artifactDir / jar.getName)
132+
IO.copyFile(pom, artifactDir / pom.getName)
133+
}
134+
cacheDir
135+
}
136+
)
137+
}

0 commit comments

Comments
 (0)