2
votes

I'm trying to make use of the provided configuration in SBT, but I'm having trouble figuring out how to get the full provided dependency classpath.

For simplicity, let's say I have two projects, A and B :

  • A has a few (JAR) dependencies, and exports compiled class files to path/to/A/target
  • B depends on A in the provided scope ( Project("B") dependsOn(A % "provided")) and exports compiled class files to path/to/B/target

In B, this returns the provided JARs, but not the provided internal dependencies :

providedDependencies <<= (update) map (_.select(Set("provided")))

This returns the internal dependencies (path/to/A/target) for every configuration, but not specifically for the provided scope, and does not output the JAR dependencies :

providedDependencies <<= (internalDependencyClasspath) map (_.files)

However, the A module shows up in the provided scope when using show update in the B project.

Any idea?

2

2 Answers

0
votes

I ended up using this task after reading this answer, but it was surprisingly hard to find :

def providedInternalDependenciesTask(proj: ProjectRef, struct: Load.BuildStructure) = {
    // "Provided" dependencies of a single ResolvedProject
    def providedDeps(op: ResolvedProject): Seq[ProjectRef] = {
      op.dependencies
        .filter(p => (p.configuration getOrElse "") == "provided")
        .map(_.project)
    }

    // Collect every "provided" dependency in the dependency graph
    def collectDeps(projRef: ProjectRef): Seq[ProjectRef] = {
      val deps = Project.getProject(projRef, struct).toSeq.flatMap(providedDeps)
      deps.flatMap(ref => ref +: collectDeps(ref)).distinct
    }

    // Return the list of "provided" internal dependencies for the ProjectRef
    // in argument.
    collectDeps(proj)
      .flatMap(exportedProducts in (_, Compile) get struct.data)
      .join.map(_.flatten.files)
  }

Usage example :

val providedInternalDependencies = TaskKey[Seq[java.io.File]]
...
providedInternalDependencies <<= (thisProjectRef, buildStructure) flatMap providedInternalDependenciesTask
0
votes

I tried the solution that F.X. provided but it kept showing me an empty dependencies list (both for provided and otherwise).

I found that you can ask the "update" task to give you the full view and then you can filter based on configuration (such as "provided").

val providedDependencies = TaskKey[Seq[java.io.File]]("task-provided-deps","The list of dependencies in the 'provided' scope")
...
providedDependencies <<= (update) map {
    up.select(configurationFilter("provided"))
},

I used this list to exclude the provided deps from getting jarred up into my "all in one" sonar plugin.