@@ -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
@@ -2099,17 +2101,128 @@ object Build {
2099
2101
)
2100
2102
)
2101
2103
2102
- lazy val commonDistSettings = Seq (
2104
+ lazy val DistCacheConfig = config(" DistCacheConfig" ) extend Compile
2105
+
2106
+ val distModules = taskKey[Seq [(ModuleID , Map [Artifact , File ])]](" fetch local artifacts for distribution." )
2107
+ val distResolvedArtifacts = taskKey[Seq [ResolvedArtifacts ]](" Resolve the dependencies for the distribution" )
2108
+ val distCaching = taskKey[File ](" cache the dependencies for the distribution" )
2109
+
2110
+ def evalPublishSteps (dependencies : Seq [ProjectReference ]): Def .Initialize [Task [Seq [(ModuleID , Map [Artifact , File ])]]] = {
2111
+ val publishAllLocalBin = dependencies.map({ d => ((d / publishLocalBin / packagedArtifacts)) }).join
2112
+ val resolveId = dependencies.map({ d => ((d / projectID)) }).join
2113
+ Def .task {
2114
+ val s = streams.value
2115
+ val log = s.log
2116
+ val published = publishAllLocalBin.value
2117
+ val ids = resolveId.value
2118
+
2119
+ ids.zip(published)
2120
+ }
2121
+ }
2122
+
2123
+ case class SimpleModuleId (org : String , name : String , revision : String ) {
2124
+ override def toString = s " $org: $name: $revision"
2125
+ }
2126
+ case class ResolvedArtifacts (id : SimpleModuleId , jar : File , pom : File )
2127
+
2128
+ def commonDistSettings (dependencies : Seq [ClasspathDep [ProjectReference ]]) = Seq (
2103
2129
packMain := Map (),
2104
2130
publishArtifact := false ,
2105
2131
packGenerateMakefile := false ,
2106
- packExpandedClasspath := true ,
2107
- packArchiveName := " scala3-" + dottyVersion
2132
+ packArchiveName := " scala3-" + dottyVersion,
2133
+ DistCacheConfig / distModules := {
2134
+ evalPublishSteps(dependencies.map(_.project)).value
2135
+ },
2136
+ DistCacheConfig / distResolvedArtifacts := {
2137
+ val localArtifactIds = (DistCacheConfig / distModules).value
2138
+ val report = (thisProjectRef / updateFull).value
2139
+
2140
+ val found = mutable.Map .empty[SimpleModuleId , ResolvedArtifacts ]
2141
+ val evicted = mutable.Set .empty[SimpleModuleId ]
2142
+
2143
+ localArtifactIds.foreach({ case (id, as) =>
2144
+ val simpleId = {
2145
+ val name0 = id.crossVersion match {
2146
+ case _ : CrossVersion .Binary =>
2147
+ // projectID does not add binary suffix
2148
+ (id.name + " _3" ).ensuring(! id.name.endsWith(" _3" ) && id.revision.startsWith(" 3." ))
2149
+ case _ => id.name
2150
+ }
2151
+ SimpleModuleId (id.organization, name0, id.revision)
2152
+ }
2153
+ var jarOrNull : File = null
2154
+ var pomOrNull : File = null
2155
+ as.foreach({ case (a, f) =>
2156
+ if (a.`type` == " jar" ) {
2157
+ jarOrNull = f
2158
+ } else if (a.`type` == " pom" ) {
2159
+ pomOrNull = f
2160
+ }
2161
+ })
2162
+ assert(jarOrNull != null , s " Could not find jar for ${id}" )
2163
+ assert(pomOrNull != null , s " Could not find pom for ${id}" )
2164
+ evicted += simpleId.copy(revision = simpleId.revision + " -nonbootstrapped" )
2165
+ found(simpleId) = ResolvedArtifacts (simpleId, jarOrNull, pomOrNull)
2166
+ })
2167
+
2168
+ report.allModuleReports.foreach { mr =>
2169
+ val simpleId = {
2170
+ val id = mr.module
2171
+ SimpleModuleId (id.organization, id.name, id.revision)
2172
+ }
2173
+
2174
+ if (! found.contains(simpleId) && ! evicted(simpleId)) {
2175
+ var jarOrNull : File = null
2176
+ var pomOrNull : File = null
2177
+ mr.artifacts.foreach({ case (a, f) =>
2178
+ if (a.`type` == " jar" || a.`type` == " bundle" ) {
2179
+ jarOrNull = f
2180
+ } else if (a.`type` == " pom" ) {
2181
+ pomOrNull = f
2182
+ }
2183
+ })
2184
+ assert(jarOrNull != null , s " Could not find jar for ${simpleId}" )
2185
+ if (pomOrNull == null ) {
2186
+ val jarPath = jarOrNull.toPath
2187
+ // we found the jar, so assume we can resolve a sibling pom file
2188
+ val pomPath = jarPath.resolveSibling(jarPath.getFileName.toString.stripSuffix(" .jar" ) + " .pom" )
2189
+ assert(Files .exists(pomPath), s " Could not find pom for ${simpleId}" )
2190
+ pomOrNull = pomPath.toFile
2191
+ }
2192
+ found(simpleId) = ResolvedArtifacts (simpleId, jarOrNull, pomOrNull)
2193
+ }
2194
+
2195
+ }
2196
+ found.values.toSeq
2197
+ },
2198
+ DistCacheConfig / distCaching := {
2199
+ val resolved = (DistCacheConfig / distResolvedArtifacts).value
2200
+ val targetDir = target.value
2201
+ val cacheDir = targetDir / " local-repo"
2202
+ val mavenRepo = cacheDir / " maven2"
2203
+ IO .createDirectory(mavenRepo)
2204
+ resolved.foreach { ra =>
2205
+ val jar = ra.jar
2206
+ val pom = ra.pom
2207
+
2208
+ val pathElems = ra.id.org.split('.' ).toVector :+ ra.id.name :+ ra.id.revision
2209
+ val artifactDir = pathElems.foldLeft(mavenRepo)(_ / _)
2210
+ IO .createDirectory(artifactDir)
2211
+ IO .copyFile(jar, artifactDir / jar.getName)
2212
+ IO .copyFile(pom, artifactDir / pom.getName)
2213
+ }
2214
+ cacheDir
2215
+ },
2216
+ Compile / pack := {
2217
+ val localRepo = (DistCacheConfig / distCaching).value
2218
+ (Compile / pack).value
2219
+ }
2108
2220
)
2109
2221
2110
2222
lazy val dist = project.asDist(Bootstrapped )
2111
2223
.settings(
2112
2224
packResourceDir += (baseDirectory.value / " bin" -> " bin" ),
2225
+ packResourceDir += (target.value / " local-repo" -> " local" ),
2113
2226
)
2114
2227
2115
2228
private def customMimaReportBinaryIssues (issueFilterLocation : String ) = mimaReportBinaryIssues := {
@@ -2240,12 +2353,24 @@ object Build {
2240
2353
def asDist (implicit mode : Mode ): Project = project.
2241
2354
enablePlugins(PackPlugin ).
2242
2355
withCommonSettings.
2243
- dependsOn(`scala3-interfaces`, dottyCompiler, dottyLibrary, tastyCore, `scala3-staging`, `scala3-tasty-inspector`, scaladoc).
2244
- settings(commonDistSettings).
2356
+ dependsOn(
2357
+ `scala3-interfaces`,
2358
+ dottyCompiler,
2359
+ dottyLibrary,
2360
+ tastyCore,
2361
+ `scala3-staging`,
2362
+ `scala3-tasty-inspector`,
2363
+ scaladoc,
2364
+ `scala3-sbt-bridge`, // for scala-cli
2365
+ ).
2366
+ withDepSettings(commonDistSettings).
2245
2367
bootstrappedSettings(
2246
2368
target := baseDirectory.value / " target" // override setting in commonBootstrappedSettings
2247
2369
)
2248
2370
2371
+ def withDepSettings (f : Seq [ClasspathDep [ProjectReference ]] => Seq [Setting [? ]]): Project =
2372
+ project.settings(f(project.dependencies))
2373
+
2249
2374
def withCommonSettings (implicit mode : Mode ): Project = project.settings(mode match {
2250
2375
case NonBootstrapped => commonNonBootstrappedSettings
2251
2376
case Bootstrapped => commonBootstrappedSettings
0 commit comments