@@ -28,26 +28,94 @@ import scala.build.testrunner.DynamicTestRunner.globPattern
28
28
import scala .util .Try
29
29
import scala .util .chaining .*
30
30
31
- final case class CrossSources (
31
+ /** CrossSources with unwrapped scripts, use [[withWrappedScripts ]] to wrap them and obtain an
32
+ * instance of CrossSources
33
+ *
34
+ * See [[CrossSources ]] for more information
35
+ *
36
+ * @param paths
37
+ * paths and realtive paths to sources on disk, wrapped in their build requirements
38
+ * @param inMemory
39
+ * in memory sources (e.g. snippets) wrapped in their build requirements
40
+ * @param defaultMainClass
41
+ * @param resourceDirs
42
+ * @param buildOptions
43
+ * build options from sources
44
+ * @param unwrappedScripts
45
+ * in memory script sources, their code must be wrapped before compiling
46
+ */
47
+ sealed class UnwrappedCrossSources (
32
48
paths : Seq [WithBuildRequirements [(os.Path , os.RelPath )]],
33
49
inMemory : Seq [WithBuildRequirements [Sources .InMemory ]],
34
50
defaultMainClass : Option [String ],
35
51
resourceDirs : Seq [WithBuildRequirements [os.Path ]],
36
- buildOptions : Seq [WithBuildRequirements [BuildOptions ]]
52
+ buildOptions : Seq [WithBuildRequirements [BuildOptions ]],
53
+ unwrappedScripts : Seq [WithBuildRequirements [Sources .UnwrappedScript ]]
37
54
) {
38
55
56
+ /** For all unwrapped script sources contained in this object wrap them according to provided
57
+ * BuildOptions
58
+ *
59
+ * @param buildOptions
60
+ * options used to choose the script wrapper
61
+ * @return
62
+ * CrossSources with all the scripts wrapped
63
+ */
64
+ def withWrappedScripts (buildOptions : BuildOptions ): CrossSources = {
65
+ val codeWrapper = ScriptPreprocessor .getScriptWrapper(buildOptions)
66
+
67
+ val wrappedScripts = unwrappedScripts.map { unwrapppedWithRequirements =>
68
+ unwrapppedWithRequirements.map(_.wrap(codeWrapper))
69
+ }
70
+
71
+ CrossSources (
72
+ paths,
73
+ inMemory ++ wrappedScripts,
74
+ defaultMainClass,
75
+ resourceDirs,
76
+ this .buildOptions
77
+ )
78
+ }
79
+
39
80
def sharedOptions (baseOptions : BuildOptions ): BuildOptions =
40
81
buildOptions
41
82
.filter(_.requirements.isEmpty)
42
83
.map(_.value)
43
84
.foldLeft(baseOptions)(_ orElse _)
44
85
45
- private def needsScalaVersion =
86
+ protected def needsScalaVersion =
46
87
paths.exists(_.needsScalaVersion) ||
47
88
inMemory.exists(_.needsScalaVersion) ||
48
89
resourceDirs.exists(_.needsScalaVersion) ||
49
90
buildOptions.exists(_.needsScalaVersion)
91
+ }
50
92
93
+ /** Information gathered from preprocessing command inputs - sources and build options from using
94
+ * directives
95
+ *
96
+ * @param paths
97
+ * paths and realtive paths to sources on disk, wrapped in their build requirements
98
+ * @param inMemory
99
+ * in memory sources (e.g. snippets and wrapped scripts) wrapped in their build requirements
100
+ * @param defaultMainClass
101
+ * @param resourceDirs
102
+ * @param buildOptions
103
+ * build options from sources
104
+ */
105
+ final case class CrossSources (
106
+ paths : Seq [WithBuildRequirements [(os.Path , os.RelPath )]],
107
+ inMemory : Seq [WithBuildRequirements [Sources .InMemory ]],
108
+ defaultMainClass : Option [String ],
109
+ resourceDirs : Seq [WithBuildRequirements [os.Path ]],
110
+ buildOptions : Seq [WithBuildRequirements [BuildOptions ]]
111
+ ) extends UnwrappedCrossSources (
112
+ paths,
113
+ inMemory,
114
+ defaultMainClass,
115
+ resourceDirs,
116
+ buildOptions,
117
+ Nil
118
+ ) {
51
119
def scopedSources (baseOptions : BuildOptions ): Either [BuildException , ScopedSources ] = either {
52
120
53
121
val sharedOptions0 = sharedOptions(baseOptions)
@@ -114,7 +182,6 @@ final case class CrossSources(
114
182
crossSources0.buildOptions.map(_.scopedValue(defaultScope))
115
183
)
116
184
}
117
-
118
185
}
119
186
120
187
object CrossSources {
@@ -141,7 +208,7 @@ object CrossSources {
141
208
suppressWarningOptions : SuppressWarningOptions ,
142
209
exclude : Seq [Positioned [String ]] = Nil ,
143
210
maybeRecoverOnError : BuildException => Option [BuildException ] = e => Some (e)
144
- )(using ScalaCliInvokeData ): Either [BuildException , (CrossSources , Inputs )] = either {
211
+ )(using ScalaCliInvokeData ): Either [BuildException , (UnwrappedCrossSources , Inputs )] = either {
145
212
146
213
def preprocessSources (elems : Seq [SingleElement ])
147
214
: Either [BuildException , Seq [PreprocessedSource ]] =
@@ -262,6 +329,16 @@ object CrossSources {
262
329
Sources .InMemory (m.originalPath, m.relPath, m.code, m.ignoreLen)
263
330
) -> m.directivesPositions
264
331
}
332
+ val unwrappedScriptsWithDirectivePositions
333
+ : Seq [(WithBuildRequirements [Sources .UnwrappedScript ], Option [DirectivesPositions ])] =
334
+ preprocessedSources.collect {
335
+ case m : PreprocessedSource .UnwrappedScript =>
336
+ val baseReqs0 = baseReqs(m.scopePath)
337
+ WithBuildRequirements (
338
+ m.requirements.fold(baseReqs0)(_ orElse baseReqs0),
339
+ Sources .UnwrappedScript (m.originalPath, m.relPath, m.wrapScriptFun)
340
+ ) -> m.directivesPositions
341
+ }
265
342
266
343
val resourceDirs : Seq [WithBuildRequirements [os.Path ]] = allInputs.elements.collect {
267
344
case r : ResourceDirectory =>
@@ -271,14 +348,20 @@ object CrossSources {
271
348
)
272
349
273
350
lazy val allPathsWithDirectivesByScope : Map [Scope , Seq [(os.Path , DirectivesPositions )]] =
274
- (pathsWithDirectivePositions ++ inMemoryWithDirectivePositions)
351
+ (pathsWithDirectivePositions ++
352
+ inMemoryWithDirectivePositions ++
353
+ unwrappedScriptsWithDirectivePositions)
275
354
.flatMap { (withBuildRequirements, directivesPositions) =>
276
355
val scope = withBuildRequirements.scopedValue(Scope .Main ).scope
277
356
val path : os.Path = withBuildRequirements.value match
278
357
case im : Sources .InMemory =>
279
358
im.originalPath match
280
359
case Right ((_, p : os.Path )) => p
281
360
case _ => inputs.workspace / im.generatedRelPath
361
+ case us : Sources .UnwrappedScript =>
362
+ us.originalPath match
363
+ case Right ((_, p : os.Path )) => p
364
+ case _ => inputs.workspace / us.generatedRelPath
282
365
case (p : os.Path , _) => p
283
366
directivesPositions.map((path, scope, _))
284
367
}
@@ -306,9 +389,20 @@ object CrossSources {
306
389
}
307
390
}
308
391
309
- val paths = pathsWithDirectivePositions.map(_._1)
310
- val inMemory = inMemoryWithDirectivePositions.map(_._1)
311
- (CrossSources (paths, inMemory, defaultMainClassOpt, resourceDirs, buildOptions), allInputs)
392
+ val paths = pathsWithDirectivePositions.map(_._1)
393
+ val inMemory = inMemoryWithDirectivePositions.map(_._1)
394
+ val unwrappedScripts = unwrappedScriptsWithDirectivePositions.map(_._1)
395
+ (
396
+ UnwrappedCrossSources (
397
+ paths,
398
+ inMemory,
399
+ defaultMainClassOpt,
400
+ resourceDirs,
401
+ buildOptions,
402
+ unwrappedScripts
403
+ ),
404
+ allInputs
405
+ )
312
406
}
313
407
314
408
private def resolveInputsFromSources (sources : Seq [Positioned [os.Path ]], enableMarkdown : Boolean ) =
0 commit comments