|
| 1 | +package ch.epfl.scala |
| 2 | + |
| 3 | +import ch.epfl.scala.githubapi._ |
| 4 | +import sbt._ |
| 5 | +import sbt.internal.util.complete._ |
| 6 | + |
| 7 | +object AnalyzeDependencyGraphDetailed { |
| 8 | + |
| 9 | + object Model { |
| 10 | + trait DetailedAnalysisAction { |
| 11 | + def name: String |
| 12 | + def help: String |
| 13 | + } |
| 14 | + object DetailedAnalysisAction { |
| 15 | + case object Get extends DetailedAnalysisAction { |
| 16 | + val name = "get" |
| 17 | + val help = "search for a pattern in the dependencies (requires githubGenerateSnapshot)" |
| 18 | + } |
| 19 | + case object List extends DetailedAnalysisAction { |
| 20 | + val name = "list" |
| 21 | + val help = "list all dependencies matching a pattern (requires githubGenerateSnapshot)" |
| 22 | + } |
| 23 | + val values: Seq[DetailedAnalysisAction] = Seq(Get, List) |
| 24 | + def fromString(str: String): Option[DetailedAnalysisAction] = values.find(_.name == str) |
| 25 | + case class AnalysisParams(action: DetailedAnalysisAction, arg: Option[String]) |
| 26 | + } |
| 27 | + case class AnalysisParams(action: DetailedAnalysisAction, arg: Option[String]) |
| 28 | + } |
| 29 | + import Model._ |
| 30 | + import AnalyzeDependencyGraph.getGithubManifest |
| 31 | + |
| 32 | + val AnalyzeDependenciesDetailed = "githubAnalyzeDependenciesDetailed" |
| 33 | + val AnalyzeDependenciesUsage: String = |
| 34 | + s"""$AnalyzeDependenciesDetailed [${DetailedAnalysisAction.values.map(_.name).mkString("|")}] [pattern]""" |
| 35 | + val AnalyzeDependenciesDetail: String = s"""Analyze the dependencies based on a search pattern: |
| 36 | + ${DetailedAnalysisAction.values.map(a => s"${a.name}: ${a.help}").mkString("\n ")} |
| 37 | + """ |
| 38 | + |
| 39 | + private def highlight(string: String, pattern: String): String = |
| 40 | + string.replaceAll(pattern, s"\u001b[32m${pattern}\u001b[0m") |
| 41 | + |
| 42 | + private def analyzeDependenciesInternal( |
| 43 | + state: State, |
| 44 | + action: DetailedAnalysisAction, |
| 45 | + pattern: String, |
| 46 | + originalPattern: String |
| 47 | + ): Unit = { |
| 48 | + def getDeps(dependencies: Seq[String], pattern: String): Seq[String] = |
| 49 | + dependencies.filter(_.contains(pattern)).map(highlight(_, originalPattern)) |
| 50 | + |
| 51 | + def blue(str: String): String = s"\u001b[34m${str}\u001b[0m" |
| 52 | + |
| 53 | + def resolvedDeps( |
| 54 | + tabs: String, |
| 55 | + acc: Seq[String], |
| 56 | + resolvedByName: Map[String, DependencyNode], |
| 57 | + pattern: String, |
| 58 | + originalPattern: String |
| 59 | + ): Seq[String] = |
| 60 | + acc ++ resolvedByName.toSeq.flatMap { |
| 61 | + case (name, resolved) => |
| 62 | + val matchingDependencies = getDeps(resolved.dependencies, pattern) |
| 63 | + if (matchingDependencies.isEmpty) { |
| 64 | + if (name.contains(pattern)) Seq(tabs + highlight(name, originalPattern)) else Nil |
| 65 | + } else { |
| 66 | + matchingDependencies.flatMap { matchingDependency => |
| 67 | + resolvedDeps(" " + tabs, acc :+ (tabs + matchingDependency), resolvedByName, name, originalPattern) |
| 68 | + } |
| 69 | + } |
| 70 | + } |
| 71 | + |
| 72 | + val matches = getGithubManifest(state) |
| 73 | + .flatMap { manifests => |
| 74 | + manifests.map { |
| 75 | + case (name, manifest) => |
| 76 | + manifest -> resolvedDeps("", Nil, manifest.resolved, pattern, originalPattern = pattern) |
| 77 | + } |
| 78 | + } |
| 79 | + .toMap |
| 80 | + |
| 81 | + action match { |
| 82 | + case DetailedAnalysisAction.Get => |
| 83 | + matches.foreach { |
| 84 | + case (manifest, deps) => |
| 85 | + println(s"📁 ${blue(manifest.name)}") |
| 86 | + println(deps.map(dep => s" $dep").mkString("\n")) |
| 87 | + } |
| 88 | + case DetailedAnalysisAction.List => |
| 89 | + println(matches.values.flatten.filter(_.contains(pattern)).toSet.mkString("\n")) |
| 90 | + } |
| 91 | + } |
| 92 | + |
| 93 | + private def extractPattern(state: State): Parser[AnalysisParams] = |
| 94 | + Parsers.any.*.map { raw => |
| 95 | + raw.mkString.trim.split(" ").toSeq match { |
| 96 | + case Seq(action, arg) => AnalysisParams(DetailedAnalysisAction.fromString(action).get, Some(arg)) |
| 97 | + case Seq(action) => AnalysisParams(DetailedAnalysisAction.fromString(action).get, None) |
| 98 | + } |
| 99 | + }.failOnException |
| 100 | + |
| 101 | + val commands: Seq[Command] = Seq( |
| 102 | + Command(AnalyzeDependenciesDetailed, (AnalyzeDependenciesUsage, AnalyzeDependenciesDetail), AnalyzeDependenciesDetail)( |
| 103 | + extractPattern |
| 104 | + )(analyzeDependencies) |
| 105 | + ) |
| 106 | + |
| 107 | + private def analyzeDependencies(state: State, params: AnalysisParams): State = { |
| 108 | + params.arg.foreach(pattern => analyzeDependenciesInternal(state, params.action, pattern, pattern)) |
| 109 | + state |
| 110 | + } |
| 111 | +} |
0 commit comments