@@ -26,6 +26,8 @@ import sbttastymima.TastyMiMaPlugin
26
26
import sbttastymima .TastyMiMaPlugin .autoImport ._
27
27
28
28
import scala .util .Properties .isJavaAtLeast
29
+ import scala .collection .mutable
30
+
29
31
import org .portablescala .sbtplatformdeps .PlatformDepsPlugin .autoImport ._
30
32
import org .scalajs .linker .interface .{ModuleInitializer , StandardConfig }
31
33
@@ -2110,17 +2112,128 @@ object Build {
2110
2112
)
2111
2113
)
2112
2114
2113
- lazy val commonDistSettings = Seq (
2115
+ lazy val DistCacheConfig = config(" DistCacheConfig" ) extend Compile
2116
+
2117
+ val distModules = taskKey[Seq [(ModuleID , Map [Artifact , File ])]](" fetch local artifacts for distribution." )
2118
+ val distResolvedArtifacts = taskKey[Seq [ResolvedArtifacts ]](" Resolve the dependencies for the distribution" )
2119
+ val distCaching = taskKey[File ](" cache the dependencies for the distribution" )
2120
+
2121
+ def evalPublishSteps (dependencies : Seq [ProjectReference ]): Def .Initialize [Task [Seq [(ModuleID , Map [Artifact , File ])]]] = {
2122
+ val publishAllLocalBin = dependencies.map({ d => ((d / publishLocalBin / packagedArtifacts)) }).join
2123
+ val resolveId = dependencies.map({ d => ((d / projectID)) }).join
2124
+ Def .task {
2125
+ val s = streams.value
2126
+ val log = s.log
2127
+ val published = publishAllLocalBin.value
2128
+ val ids = resolveId.value
2129
+
2130
+ ids.zip(published)
2131
+ }
2132
+ }
2133
+
2134
+ case class SimpleModuleId (org : String , name : String , revision : String ) {
2135
+ override def toString = s " $org: $name: $revision"
2136
+ }
2137
+ case class ResolvedArtifacts (id : SimpleModuleId , jar : File , pom : File )
2138
+
2139
+ def commonDistSettings (dependencies : Seq [ClasspathDep [ProjectReference ]]) = Seq (
2114
2140
packMain := Map (),
2115
2141
publishArtifact := false ,
2116
2142
packGenerateMakefile := false ,
2117
- packExpandedClasspath := true ,
2118
- packArchiveName := " scala3-" + dottyVersion
2143
+ packArchiveName := " scala3-" + dottyVersion,
2144
+ DistCacheConfig / distModules := {
2145
+ evalPublishSteps(dependencies.map(_.project)).value
2146
+ },
2147
+ DistCacheConfig / distResolvedArtifacts := {
2148
+ val localArtifactIds = (DistCacheConfig / distModules).value
2149
+ val report = (thisProjectRef / updateFull).value
2150
+
2151
+ val found = mutable.Map .empty[SimpleModuleId , ResolvedArtifacts ]
2152
+ val evicted = mutable.Set .empty[SimpleModuleId ]
2153
+
2154
+ localArtifactIds.foreach({ case (id, as) =>
2155
+ val simpleId = {
2156
+ val name0 = id.crossVersion match {
2157
+ case _ : CrossVersion .Binary =>
2158
+ // projectID does not add binary suffix
2159
+ (id.name + " _3" ).ensuring(! id.name.endsWith(" _3" ) && id.revision.startsWith(" 3." ))
2160
+ case _ => id.name
2161
+ }
2162
+ SimpleModuleId (id.organization, name0, id.revision)
2163
+ }
2164
+ var jarOrNull : File = null
2165
+ var pomOrNull : File = null
2166
+ as.foreach({ case (a, f) =>
2167
+ if (a.`type` == " jar" ) {
2168
+ jarOrNull = f
2169
+ } else if (a.`type` == " pom" ) {
2170
+ pomOrNull = f
2171
+ }
2172
+ })
2173
+ assert(jarOrNull != null , s " Could not find jar for ${id}" )
2174
+ assert(pomOrNull != null , s " Could not find pom for ${id}" )
2175
+ evicted += simpleId.copy(revision = simpleId.revision + " -nonbootstrapped" )
2176
+ found(simpleId) = ResolvedArtifacts (simpleId, jarOrNull, pomOrNull)
2177
+ })
2178
+
2179
+ report.allModuleReports.foreach { mr =>
2180
+ val simpleId = {
2181
+ val id = mr.module
2182
+ SimpleModuleId (id.organization, id.name, id.revision)
2183
+ }
2184
+
2185
+ if (! found.contains(simpleId) && ! evicted(simpleId)) {
2186
+ var jarOrNull : File = null
2187
+ var pomOrNull : File = null
2188
+ mr.artifacts.foreach({ case (a, f) =>
2189
+ if (a.`type` == " jar" || a.`type` == " bundle" ) {
2190
+ jarOrNull = f
2191
+ } else if (a.`type` == " pom" ) {
2192
+ pomOrNull = f
2193
+ }
2194
+ })
2195
+ assert(jarOrNull != null , s " Could not find jar for ${simpleId}" )
2196
+ if (pomOrNull == null ) {
2197
+ val jarPath = jarOrNull.toPath
2198
+ // we found the jar, so assume we can resolve a sibling pom file
2199
+ val pomPath = jarPath.resolveSibling(jarPath.getFileName.toString.stripSuffix(" .jar" ) + " .pom" )
2200
+ assert(Files .exists(pomPath), s " Could not find pom for ${simpleId}" )
2201
+ pomOrNull = pomPath.toFile
2202
+ }
2203
+ found(simpleId) = ResolvedArtifacts (simpleId, jarOrNull, pomOrNull)
2204
+ }
2205
+
2206
+ }
2207
+ found.values.toSeq
2208
+ },
2209
+ DistCacheConfig / distCaching := {
2210
+ val resolved = (DistCacheConfig / distResolvedArtifacts).value
2211
+ val targetDir = target.value
2212
+ val cacheDir = targetDir / " local-repo"
2213
+ val mavenRepo = cacheDir / " maven2"
2214
+ IO .createDirectory(mavenRepo)
2215
+ resolved.foreach { ra =>
2216
+ val jar = ra.jar
2217
+ val pom = ra.pom
2218
+
2219
+ val pathElems = ra.id.org.split('.' ).toVector :+ ra.id.name :+ ra.id.revision
2220
+ val artifactDir = pathElems.foldLeft(mavenRepo)(_ / _)
2221
+ IO .createDirectory(artifactDir)
2222
+ IO .copyFile(jar, artifactDir / jar.getName)
2223
+ IO .copyFile(pom, artifactDir / pom.getName)
2224
+ }
2225
+ cacheDir
2226
+ },
2227
+ Compile / pack := {
2228
+ val localRepo = (DistCacheConfig / distCaching).value
2229
+ (Compile / pack).value
2230
+ }
2119
2231
)
2120
2232
2121
2233
lazy val dist = project.asDist(Bootstrapped )
2122
2234
.settings(
2123
2235
packResourceDir += (baseDirectory.value / " bin" -> " bin" ),
2236
+ packResourceDir += (target.value / " local-repo" -> " local" ),
2124
2237
)
2125
2238
2126
2239
private def customMimaReportBinaryIssues (issueFilterLocation : String ) = mimaReportBinaryIssues := {
@@ -2251,12 +2364,24 @@ object Build {
2251
2364
def asDist (implicit mode : Mode ): Project = project.
2252
2365
enablePlugins(PackPlugin ).
2253
2366
withCommonSettings.
2254
- dependsOn(`scala3-interfaces`, dottyCompiler, dottyLibrary, tastyCore, `scala3-staging`, `scala3-tasty-inspector`, scaladoc).
2255
- settings(commonDistSettings).
2367
+ dependsOn(
2368
+ `scala3-interfaces`,
2369
+ dottyCompiler,
2370
+ dottyLibrary,
2371
+ tastyCore,
2372
+ `scala3-staging`,
2373
+ `scala3-tasty-inspector`,
2374
+ scaladoc,
2375
+ `scala3-sbt-bridge`, // for scala-cli
2376
+ ).
2377
+ withDepSettings(commonDistSettings).
2256
2378
bootstrappedSettings(
2257
2379
target := baseDirectory.value / " target" // override setting in commonBootstrappedSettings
2258
2380
)
2259
2381
2382
+ def withDepSettings (f : Seq [ClasspathDep [ProjectReference ]] => Seq [Setting [? ]]): Project =
2383
+ project.settings(f(project.dependencies))
2384
+
2260
2385
def withCommonSettings (implicit mode : Mode ): Project = project.settings(mode match {
2261
2386
case NonBootstrapped => commonNonBootstrappedSettings
2262
2387
case Bootstrapped => commonBootstrappedSettings
0 commit comments