-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
1,448 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
109 changes: 109 additions & 0 deletions
109
extractor/src/main/scala/org/jetbrains/sbt/processors/EvictionsProcessor.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
package org.jetbrains.sbt | ||
package processors | ||
|
||
import org.jetbrains.sbt.Utilities._ | ||
import org.jetbrains.sbt.structure.{ModuleDependencyData, ModuleIdentifier, ProjectData} | ||
import org.jetbrains.sbt.{structure => jb} | ||
import sbt._ | ||
|
||
import scala.collection.mutable | ||
|
||
/** | ||
* @author Nikolay Obedin | ||
* @since 9/15/15. | ||
*/ | ||
object EvictionsProcessor { | ||
def apply(acceptedProjectRefs: Seq[ProjectRef], projectsData: Seq[ProjectData])(implicit state: State, options: Options): Seq[ProjectData] = | ||
if (options.download) | ||
new EvictionsProcessor(acceptedProjectRefs, projectsData).process() | ||
else | ||
projectsData | ||
} | ||
|
||
class EvictionsProcessor(acceptedProjectRefs: Seq[ProjectRef], projectsData: Seq[ProjectData]) extends Extractor with Configurations with Modules { | ||
|
||
private case class Eviction(configuration: jb.Configuration, from: ModuleIdentifier, to: ModuleIdentifier) | ||
|
||
private var evictions = Map.empty[String, Seq[Eviction]] | ||
private var dependencies = Map.empty[String, Seq[ProjectData]] | ||
private val evictionsApplied = mutable.HashSet.empty[String] | ||
|
||
private def process()(implicit state: State): Seq[ProjectData] = { | ||
init() | ||
sortByProjectDependencies(projectsData).flatMap { project => | ||
if (!evictionsApplied(project.id)) | ||
processProjectAndDeps(project, Set.empty) | ||
else | ||
Seq.empty | ||
} | ||
} | ||
|
||
private def processProjectAndDeps(project: ProjectData, currentEvictions: Set[Eviction]): Seq[ProjectData] = { | ||
val updatedEvictions = currentEvictions ++ evictions(project.id) | ||
val updatedProject = applyEvictions(project, updatedEvictions) | ||
val updatedDependencies = dependencies(project.id).flatMap(processProjectAndDeps(_, updatedEvictions)) | ||
updatedProject +: updatedDependencies | ||
} | ||
|
||
private def applyEvictions(project: ProjectData, currentEvictions: Set[Eviction]): ProjectData = { | ||
evictionsApplied.add(project.id) | ||
currentEvictions.foldLeft(project)(applyEviction) | ||
} | ||
|
||
private def applyEviction(project: ProjectData, eviction: Eviction): ProjectData = { | ||
val updatedModules = project.dependencies.modules.flatMap(applyEviction(_, eviction)) | ||
project.copy(dependencies = project.dependencies.copy(modules = updatedModules)) | ||
} | ||
|
||
private def applyEviction(module: ModuleDependencyData, eviction: Eviction): Seq[ModuleDependencyData] = | ||
if (module.configurations.contains(eviction.configuration) && module.id == eviction.from) { | ||
val unaffectedConfigurations = module.configurations.filterNot(_ == eviction.configuration) | ||
val evictedDependency = ModuleDependencyData(eviction.to, Seq(eviction.configuration)) | ||
if (unaffectedConfigurations.isEmpty) | ||
Seq(evictedDependency) | ||
else | ||
Seq(evictedDependency, ModuleDependencyData(module.id, unaffectedConfigurations)) | ||
} else { | ||
Seq(module) | ||
} | ||
|
||
private def sortByProjectDependencies(projects: Seq[ProjectData]): Seq[ProjectData] = | ||
Dag.topologicalSort(projectsData)(p => dependencies(p.id)).reverse | ||
|
||
private def init()(implicit state: State): Unit = { | ||
dependencies = projectsData.map(p => (p.id, getDependencies(p))).toMap | ||
evictions = acceptedProjectRefs.map(p => (p.id, getEvictions(p))).toMap | ||
evictionsApplied.clear() | ||
} | ||
|
||
private def getDependencies(project: ProjectData): Seq[ProjectData] = { | ||
val ids = project.dependencies.projects.map(_.project) | ||
projectsData.filter(p => ids.contains(p.id)) | ||
} | ||
|
||
private def getEvictions(projectRef: ProjectRef)(implicit state: State): Seq[Eviction] = { | ||
implicit val projectRefImplicit = projectRef | ||
projectTask(Keys.update).map { updateReport => | ||
for { | ||
confReport <- updateReport.configurations | ||
if getDependencyConfigurations(state, projectRef).contains(config(confReport.configuration)) | ||
conf = jb.Configuration(confReport.configuration) | ||
from <- confReport.evicted | ||
fromId <- toModuleIdentifiers(from) | ||
to <- confReport.allModules | ||
toId <- toModuleIdentifiers(to) | ||
if compareModulesWithoutVersion(fromId, toId) | ||
} yield { | ||
Eviction(conf, fromId, toId) | ||
} | ||
}.getOrElse(Seq.empty) | ||
} | ||
|
||
private def toModuleIdentifiers(moduleId: ModuleID): Seq[ModuleIdentifier] = { | ||
val artifacts = if (moduleId.explicitArtifacts.nonEmpty) moduleId.explicitArtifacts else Seq(Artifact("", "")) | ||
createModuleIdentifiers(moduleId, artifacts) | ||
} | ||
|
||
private def compareModulesWithoutVersion(fst: ModuleIdentifier, snd: ModuleIdentifier): Boolean = | ||
fst.name == snd.name && fst.organization == snd.organization && fst.artifactType == snd.artifactType && fst.classifier == snd.classifier | ||
} |
21 changes: 21 additions & 0 deletions
21
extractor/src/main/scala/org/jetbrains/sbt/processors/UnusedLibrariesProcessor.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package org.jetbrains.sbt | ||
package processors | ||
|
||
import org.jetbrains.sbt.structure.{ModuleIdentifier, RepositoryData, ProjectData} | ||
|
||
/** | ||
* @author Nikolay Obedin | ||
* @since 10/6/15. | ||
*/ | ||
class UnusedLibrariesProcessor(projectsData: Seq[ProjectData], repositoryData: RepositoryData) { | ||
private def process(): RepositoryData = | ||
repositoryData.copy(modules = repositoryData.modules.filter(lib => usedModules.contains(lib.id))) | ||
|
||
private def usedModules: Set[ModuleIdentifier] = | ||
projectsData.flatMap(_.dependencies.modules.map(_.id)).toSet | ||
} | ||
|
||
object UnusedLibrariesProcessor { | ||
def apply(projectData: Seq[ProjectData])(repositoryData: RepositoryData): RepositoryData = | ||
new UnusedLibrariesProcessor(projectData, repositoryData).process() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import sbt._ | ||
import Keys._ | ||
|
||
object MyBuild extends Build { | ||
lazy val childOne = project | ||
.settings( | ||
libraryDependencies += "com.google.protobuf" % "protobuf-java" % "2.3.0" | ||
) | ||
|
||
lazy val childTwo = project | ||
.dependsOn(childOne) | ||
.settings( | ||
libraryDependencies += "com.google.protobuf" % "protobuf-java" % "2.5.0" | ||
) | ||
|
||
lazy val eviction = project.in(file(".")).aggregate(childOne, childTwo) | ||
} |
Oops, something went wrong.