Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question: Inter-Project Dependencies #14

Open
diesalbla opened this issue Sep 24, 2018 · 2 comments
Open

Question: Inter-Project Dependencies #14

diesalbla opened this issue Sep 24, 2018 · 2 comments

Comments

@diesalbla
Copy link

This is an issue-discussion, but I have no inner SBT knowledge to know if this is feasible.

This is a great plugin for detecting the unused or undeclared entries in libraryDependencies, the ones that SBT has to resolve through ivy. However, there are Scala repositories that may be organised with a multi-project build, which may have scores of subprojects, which are also interconnected with interproject dependencies. This creates several challenges for explicit dependency declaration.

  • First, the same non-explicit transitive dependencies between libraries, may also appear between subprojects, for example if a subproject A declares a dependency on B, and B declares one on C, but A is invoking a function from C through its declared dependency on B.
  • Second, and also between subprojects, it may happen that A declares dependency on subproject B that is not needed.
  • Finally, there is the interaction between library dependencies and dependencies between sub-projects. One sub-project A, which declares a dependency on a sub-project B, may be using a library dependency that it nether declares, nor is it a transitive library dependency of those that A declares, but which is a library dependency (explicit of transitive) of sub-project B.

The goal of this issue would be to investigate how these problems can be solved in this plugin.

@cb372
Copy link
Owner

cb372 commented Sep 26, 2018

I had a quick play around with what's available in sbt and zinc, and I think we could do something.

foo := {
  println("Declared dependencies:")
  println(buildDependencies.value.classpathRefs(thisProjectRef.value))
  println("allExternalDeps:")
  compile.in(Compile).value.asInstanceOf[sbt.internal.inc.Analysis].relations.allExternalDeps.foreach(println)
}
sbt:scalacache> cats-effect/foo
Declared dependencies:
List(ProjectRef(file:/Users/chris/code/scalacache/,coreJVM))
allExternalDeps:
scalacache.Async
scalacache.Mode

The first part of the output shows us that the cats-effect project (in ScalaCache) declares a dependency on the coreJVM project.

The second part shows that the project depends on 2 classes in other projects for its compilation. Both of these classes are in the coreJVM project.

So a rough implementation would look like:

  1. Get the list of projects that this project declares a dependency on

  2. Compile all projects

  3. Look in each project's target directory to build a data structure of which projects contain which classes. So a Map[ProjectRef, Set[String]] or something similar. (Maybe there's an easier way to get this info from sbt without having to traverse the target directory.)

  4. Use that data, along with the allExternalDeps, to work out which projects this project actually depends on for compilation. Let's call this result actual dependencies.

Then it's simply

undeclared dependencies = actual dependencies - declared dependencies

and

unused dependencies = declared dependencies - actual dependencies

@anchika
Copy link

anchika commented Mar 23, 2019

This plugin is great to find unused dependencies on single project.
Any updates on how to find unused dependencies in multi-project using this plugin?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants