summaryrefslogtreecommitdiff
path: root/scalalib/src/mill/scalalib/dependency/versions/VersionsFinder.scala
blob: b1033688ff647e5aac9f478f8f0b89b240400788 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package mill.scalalib.dependency.versions

import mill.define.{BaseModule, Task}
import mill.eval.Evaluator
import mill.scalalib.dependency.metadata.MetadataLoaderFactory
import mill.scalalib.{Dep, JavaModule, Lib}
import mill.util.Ctx.{Home, Log}
import mill.util.{Loose, Strict}

private[dependency] object VersionsFinder {

  def findVersions(ctx: Log with Home,
                   rootModule: BaseModule): Seq[ModuleDependenciesVersions] = {
    val evaluator =
      new Evaluator(ctx.home, os.pwd / 'out, os.pwd / 'out, rootModule, ctx.log)

    val javaModules = rootModule.millInternal.modules.collect {
      case javaModule: JavaModule => javaModule
    }

    val resolvedDependencies = resolveDependencies(evaluator, javaModules)
    resolveVersions(resolvedDependencies)
  }

  private def resolveDependencies(evaluator: Evaluator,
                                  javaModules: Seq[JavaModule]) =
    javaModules.map { javaModule =>
      val depToDependency =
        eval(evaluator, javaModule.resolveCoursierDependency)
      val deps = evalOrElse(evaluator, javaModule.ivyDeps, Loose.Agg.empty[Dep])

      val (dependencies, _) =
        Lib.resolveDependenciesMetadata(javaModule.repositories,
                                        depToDependency,
                                        deps)

      (javaModule, dependencies)
    }

  private def resolveVersions(resolvedDependencies: Seq[ResolvedDependencies]) =
    resolvedDependencies.map {
      case (javaModule, dependencies) =>
        val metadataLoaders =
          javaModule.repositories.flatMap(MetadataLoaderFactory(_))

        val versions = dependencies.map { dependency =>
          val currentVersion = Version(dependency.version)
          val allVersions =
            metadataLoaders
              .flatMap(_.getVersions(dependency.module))
              .toSet
          DependencyVersions(dependency, currentVersion, allVersions)
        }

        ModuleDependenciesVersions(javaModule, versions)
    }

  private def eval[T](evaluator: Evaluator, e: Task[T]): T =
    evaluator.evaluate(Strict.Agg(e)).values match {
      case Seq()     => throw new NoSuchElementException
      case Seq(e: T) => e
    }

  private def evalOrElse[T](evaluator: Evaluator,
                            e: Task[T],
                            default: => T): T =
    evaluator.evaluate(Strict.Agg(e)).values match {
      case Seq()     => default
      case Seq(e: T) => e
    }

  private type ResolvedDependencies = (JavaModule, Seq[coursier.Dependency])
}