Skip to content

Commit 8b031bd

Browse files
zygiert1990Michał Zygagemini-code-assist[bot]xerialclaude
authored
Add packIncludedProjectScopes setting for filtering project dependency scopes (#592)
* add include dependency mappings key * Update src/main/scala/xerial/sbt/pack/PackPlugin.scala Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> * add additional test for case where mappings sequence is empty * Revert "Update src/main/scala/xerial/sbt/pack/PackPlugin.scala" This reverts commit dd6d132. * Rename includedDependencyMappings to packIncludedProjectScopes - Follow pack* naming convention for consistency with other settings - Use "project scopes" instead of "dependency mappings" to avoid confusion with JAR dependency mapping - Update documentation with clearer description and example 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Michał Zyga <michal.zyga@softwaremill.com> Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Co-authored-by: Taro L. Saito <leo@xerial.org> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent dd27f25 commit 8b031bd

File tree

4 files changed

+48
-15
lines changed

4 files changed

+48
-15
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,9 @@ the `packCopyDependenciesTarget` setting.
201201
By default, a symbolic link will be created. By setting `packCopyDependenciesUseSymbolicLinks` to `false`,
202202
the files will be copied instead of symlinking. A symbolic link is faster and uses less disk space.
203203

204+
By default, only dependencies from child modules with scope `compile->` will be copied. By setting
205+
`packIncludedProjectScopes` to a list of scopes (e.g., `Seq("compile->", "test->")`), you can control which project dependencies are included.
206+
204207
It can be used e.g. for copying dependencies of a webapp to `WEB-INF/lib`
205208

206209
See an [example](src/sbt-test/sbt-pack/copy-dependencies) project.

src/main/scala/xerial/sbt/pack/PackPlugin.scala

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ object PackPlugin extends AutoPlugin with PackArchive {
9696
taskKey[Boolean]("""use symbolic links instead of copying for <packCopyDependencies>.
9797
|The use of symbolic links allows faster processing and save disk space.
9898
""".stripMargin)
99+
val packIncludedProjectScopes =
100+
settingKey[Seq[String]]("project dependency scopes to include when packaging, default is Seq(\"compile->\")")
99101

100102
val packArchivePrefix = settingKey[String]("prefix of (prefix)-(version).(format) archive file name")
101103
val packArchiveName = settingKey[String]("archive file name. Default is (project-name)-(version)")
@@ -157,7 +159,8 @@ object PackPlugin extends AutoPlugin with PackArchive {
157159
Runtime,
158160
discoveredMainClasses,
159161
state.value,
160-
packExclude.value
162+
packExclude.value,
163+
packIncludedProjectScopes.value
161164
)
162165
Def.task {
163166
mainClasses.value
@@ -166,7 +169,14 @@ object PackPlugin extends AutoPlugin with PackArchive {
166169
}.value,
167170
packAllUnmanagedJars := Def.taskDyn {
168171
val allUnmanagedJars =
169-
getFromSelectedProjects(thisProjectRef.value, Runtime, unmanagedJars, state.value, packExclude.value)
172+
getFromSelectedProjects(
173+
thisProjectRef.value,
174+
Runtime,
175+
unmanagedJars,
176+
state.value,
177+
packExclude.value,
178+
packIncludedProjectScopes.value
179+
)
170180
Def.task { allUnmanagedJars.value }
171181
}.value,
172182
Def.derive(
@@ -178,7 +188,8 @@ object PackPlugin extends AutoPlugin with PackArchive {
178188
c,
179189
packageBin,
180190
state.value,
181-
packExcludeLibJars.value
191+
packExcludeLibJars.value,
192+
packIncludedProjectScopes.value
182193
)
183194
) ++ c.extendsConfigs.flatMap(libJarsFromConfiguration)
184195

@@ -244,6 +255,7 @@ object PackPlugin extends AutoPlugin with PackArchive {
244255
}
245256
),
246257
packCopyDependenciesUseSymbolicLinks := true,
258+
packIncludedProjectScopes := Seq("compile->"),
247259
packCopyDependenciesTarget := target.value / "lib",
248260
Def.derive(
249261
packCopyDependencies := {
@@ -507,34 +519,28 @@ object PackPlugin extends AutoPlugin with PackArchive {
507519
})
508520
)
509521

510-
private def getFromAllProjects[T](
511-
contextProject: ProjectRef,
512-
config: Configuration,
513-
targetTask: TaskKey[T],
514-
state: State
515-
): Task[Seq[(T, ProjectRef)]] =
516-
getFromSelectedProjects(contextProject, config, targetTask, state, Seq.empty)
517-
518522
private def getFromSelectedProjects[T](
519523
contextProject: ProjectRef,
520524
config: Configuration,
521525
targetTask: TaskKey[T],
522526
state: State,
523-
exclude: Seq[String]
527+
exclude: Seq[String],
528+
packIncludedProjectScopes: Seq[String]
524529
): Task[Seq[(T, ProjectRef)]] = {
525530
val extracted = Project.extract(state)
526531
val structure = extracted.structure
527532

528533
def transitiveDependencies(currentProject: ProjectRef): Seq[ProjectRef] = {
529534
def isExcluded(p: ProjectRef) = exclude.contains(p.project)
530535

531-
def isCompileConfig(cp: ClasspathDep[ProjectRef]) = cp.configuration.forall(_.contains("compile->"))
536+
def isMatchingConfig(cp: ClasspathDep[ProjectRef]) =
537+
cp.configuration.forall(c => packIncludedProjectScopes.exists(c.contains(_)))
532538

533539
// Traverse all dependent projects
534540
val children = Project
535541
.getProject(currentProject, structure)
536542
.toSeq
537-
.flatMap { _.dependencies.filter(isCompileConfig).map(_.project) }
543+
.flatMap { _.dependencies.filter(isMatchingConfig).map(_.project) }
538544

539545
(currentProject +: (children flatMap transitiveDependencies)) filterNot (isExcluded)
540546
}

src/sbt-test/sbt-pack/copy-dependencies/build.sbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ lazy val module3 =
5151

5252
lazy val module4 =
5353
project
54-
.dependsOn(module2)
54+
.dependsOn(module2, module3 % "test->compile")
5555
.settings(commonSettings)
5656
.settings(
5757
libraryDependencies ++= Seq(

src/sbt-test/sbt-pack/copy-dependencies/test

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,27 @@ $exists module4/target/WEB-INF/lib/commons-digester-2.1.jar
6161
$exists module4/target/WEB-INF/lib/commons-logging-1.1.1.jar
6262
$exists module4/target/WEB-INF/lib/slf4j-api-1.7.6.jar
6363
-$exists module4/target/WEB-INF/lib/snappy-java-1.1.1.6.jar
64+
65+
>set module4 / packIncludedProjectScopes := Seq("compile->", "test->")
66+
>module4 / packCopyDependencies
67+
#$exec ls module4/target/WEB-INF/lib
68+
-$exists module4/target/WEB-INF/lib/module2-0.1.jar
69+
$exists module4/target/WEB-INF/lib/module3-0.1.jar
70+
$exists module4/target/WEB-INF/lib/module4-0.1.jar
71+
$exists module4/target/WEB-INF/lib/commons-collections-3.2.1.jar
72+
$exists module4/target/WEB-INF/lib/commons-digester-2.1.jar
73+
$exists module4/target/WEB-INF/lib/commons-logging-1.1.1.jar
74+
$exists module4/target/WEB-INF/lib/slf4j-api-1.7.6.jar
75+
-$exists module4/target/WEB-INF/lib/snappy-java-1.1.1.6.jar
76+
77+
>set module4 / packIncludedProjectScopes := Seq()
78+
>module4 / packCopyDependencies
79+
#$exec ls module4/target/WEB-INF/lib
80+
-$exists module4/target/WEB-INF/lib/module2-0.1.jar
81+
-$exists module4/target/WEB-INF/lib/module3-0.1.jar
82+
$exists module4/target/WEB-INF/lib/module4-0.1.jar
83+
$exists module4/target/WEB-INF/lib/commons-collections-3.2.1.jar
84+
$exists module4/target/WEB-INF/lib/commons-digester-2.1.jar
85+
$exists module4/target/WEB-INF/lib/commons-logging-1.1.1.jar
86+
$exists module4/target/WEB-INF/lib/slf4j-api-1.7.6.jar
87+
-$exists module4/target/WEB-INF/lib/snappy-java-1.1.1.6.jar

0 commit comments

Comments
 (0)