Skip to content

Commit

Permalink
Merge pull request #902 from coursier/topic/remove-attributes-hack
Browse files Browse the repository at this point in the history
Rework attributes handling
  • Loading branch information
alexarchambault committed Oct 9, 2018
2 parents 320ef97 + 282daa0 commit 4909c5e
Show file tree
Hide file tree
Showing 51 changed files with 1,184 additions and 984 deletions.
1 change: 1 addition & 0 deletions build.sbt
Expand Up @@ -28,6 +28,7 @@ lazy val core = crossProject("core")(JSPlatform, JVMPlatform)
.settings(
shared,
coursierPrefix,
libs += Deps.scalaReflect.value % Provided,
Mima.previousArtifacts,
Mima.coreFilters
)
Expand Down
4 changes: 2 additions & 2 deletions doc/docs/api.md
Expand Up @@ -36,10 +36,10 @@ Resolving dependencies involves create an initial resolution state, with all the
val start = Resolution(
Set(
Dependency(
Module("org.typelevel", "cats-core_2.11"), "0.6.0"
Module(org"org.typelevel", name"cats-core_2.11"), "0.6.0"
),
Dependency(
Module("org.scalaz", "scalaz-core_2.11"), "7.2.3"
Module(org"org.scalaz", name"scalaz-core_2.11"), "7.2.3"
)
)
)
Expand Down
4 changes: 2 additions & 2 deletions doc/docs/quick-start-api.md
Expand Up @@ -53,10 +53,10 @@ To resolve dependencies, first create a `Resolution` case class with your depend
val start = Resolution(
Set(
Dependency(
Module("org.scalaz", "scalaz-core_2.11"), "7.2.3"
Module(org"org.scalaz", name"scalaz-core_2.11"), "7.2.3"
),
Dependency(
Module("org.typelevel", "cats-core_2.11"), "0.6.0"
Module(org"org.typelevel", name"cats-core_2.11"), "0.6.0"
)
)
)
Expand Down
5 changes: 3 additions & 2 deletions modules/cli/src/main/scala-2.12/coursier/cli/Fetch.scala
Expand Up @@ -5,6 +5,7 @@ import java.io.File

import caseapp._
import coursier.cli.options.FetchOptions
import coursier.core.Classifier

final class Fetch(options: FetchOptions, args: RemainingArgs) {

Expand All @@ -14,8 +15,8 @@ final class Fetch(options: FetchOptions, args: RemainingArgs) {
sources = options.sources,
javadoc = options.javadoc,
artifactTypes = options.artifactOptions.artifactTypes(
options.sources || options.common.classifier0("sources"),
options.javadoc || options.common.classifier0("javadoc")
options.sources || options.common.classifier0(Classifier.sources),
options.javadoc || options.common.classifier0(Classifier.javadoc)
)
)

Expand Down
113 changes: 59 additions & 54 deletions modules/cli/src/main/scala-2.12/coursier/cli/Helper.scala
Expand Up @@ -9,6 +9,7 @@ import java.util.jar.{Manifest => JManifest}
import coursier.cli.options.{CommonOptions, IsolatedLoaderOptions}
import coursier.cli.scaladex.Scaladex
import coursier.cli.util.{JsonElem, JsonPrintRequirement, JsonReport}
import coursier.core.{Classifier, Type}
import coursier.extra.Typelevel
import coursier.interop.scalaz._
import coursier.ivy.IvyRepository
Expand Down Expand Up @@ -230,30 +231,34 @@ class Helper(
.mkString("\n")
}

val globalExcludes: Set[(String, String)] = excludesNoAttr.map { mod =>
(mod.organization, mod.name)
}.toSet
val globalExcludes: Set[(Organization, ModuleName)] =
excludesNoAttr
.map(mod => (mod.organization, mod.name))
.toSet

val localExcludeMap: Map[String, Set[(String, String)]] =
val localExcludeMap: Map[String, Set[(Organization, ModuleName)]] =
if (localExcludeFile.isEmpty) {
Map()
} else {
val source = scala.io.Source.fromFile(localExcludeFile)
val lines = try source.mkString.split("\n") finally source.close()

lines.map({ str =>
val parent_and_child = str.split("--")
if (parent_and_child.length != 2) {
throw new SoftExcludeParsingException(s"Failed to parse $str")
}
lines
.map { str =>
val parent_and_child = str.split("--")
if (parent_and_child.length != 2)
throw new SoftExcludeParsingException(s"Failed to parse $str")

val child_org_name = parent_and_child(1).split(":")
if (child_org_name.length != 2) {
throw new SoftExcludeParsingException(s"Failed to parse $child_org_name")
}
val child_org_name = parent_and_child(1).split(":")
if (child_org_name.length != 2)
throw new SoftExcludeParsingException(s"Failed to parse $child_org_name")

(parent_and_child(0), (child_org_name(0), child_org_name(1)))
}).groupBy(_._1).mapValues(_.map(_._2).toSet).toMap
(parent_and_child(0), (Organization(child_org_name(0)), ModuleName(child_org_name(1))))
}
.groupBy(_._1)
.mapValues(_.map(_._2).toSet)
.iterator
.toMap
}

val moduleReq = ModuleRequirements(globalExcludes, localExcludeMap, defaultConfiguration)
Expand Down Expand Up @@ -303,7 +308,7 @@ class Helper(

for (((mod, version), _) <- depsWithUrls if forceVersions.get(mod).exists(_ != version))
throw new Exception(s"Cannot force a version that is different from the one specified " +
s"for the module ${mod}:${version} with url")
s"for the module $mod:$version with url")

val checksums = {
val splitChecksumArgs = checksum.flatMap(_.split(',')).filter(_.nonEmpty)
Expand Down Expand Up @@ -560,7 +565,7 @@ class Helper(
def artifacts(
sources: Boolean,
javadoc: Boolean,
artifactTypes: Set[String],
artifactTypes: Set[Type],
subset: Set[Dependency] = null
): Seq[Artifact] = {

Expand All @@ -583,41 +588,42 @@ class Helper(

val res0 = Option(subset).fold(res)(res.subset)

val depArtTuples: Seq[(Dependency, Artifact)] = getDepArtifactsForClassifier(sources, javadoc, res0)
val artifacts0 = getDepArtifactsForClassifier(sources, javadoc, res0).map(t => (t._2, t._3))

val artifacts0 = depArtTuples.map(_._2)

if (artifactTypes("*"))
artifacts0
if (artifactTypes(Type("*")))
artifacts0.map(_._2)
else
artifacts0.filter { artifact =>
artifactTypes(artifact.`type`)
artifacts0.collect {
case (attr, artifact) if artifactTypes(attr.`type`) =>
artifact
}
}

private def getDepArtifactsForClassifier(sources: Boolean, javadoc: Boolean, res0: Resolution): Seq[(Dependency, Artifact)] = {
val raw: Seq[(Dependency, Artifact)] = if (hasOverrideClassifiers(sources, javadoc)) {
//TODO: this function somehow gives duplicated things
res0.dependencyClassifiersArtifacts(overrideClassifiers(sources, javadoc).toVector.sorted)
} else {
res0.dependencyArtifacts(withOptional = true)
}
private def getDepArtifactsForClassifier(sources: Boolean, javadoc: Boolean, res0: Resolution): Seq[(Dependency, Attributes, Artifact)] = {
val raw =
if (hasOverrideClassifiers(sources, javadoc))
//TODO: this function somehow gives duplicated things
res0.dependencyArtifacts(Some(overrideClassifiers(sources, javadoc).toVector.sorted))
else
res0.dependencyArtifacts(None)

raw.map({ case (dep, artifact) =>
raw.map {
case (dep, attr, artifact) =>
(
dep.copy(
attributes = dep.attributes.copy(classifier = artifact.classifier)),
attributes = dep.attributes.copy(classifier = attr.classifier)),
attr,
artifact
)
})
}
}

private def overrideClassifiers(sources: Boolean, javadoc:Boolean): Set[String] = {
private def overrideClassifiers(sources: Boolean, javadoc:Boolean): Set[Classifier] = {
var classifiers = classifier0
if (sources)
classifiers = classifiers + "sources"
classifiers = classifiers + Classifier.sources
if (javadoc)
classifiers = classifiers + "javadoc"
classifiers = classifiers + Classifier.javadoc
classifiers
}

Expand All @@ -628,13 +634,11 @@ class Helper(
def fetchMap(
sources: Boolean,
javadoc: Boolean,
artifactTypes: Set[String],
artifactTypes: Set[Type],
subset: Set[Dependency] = null
): Map[String, File] = {

val artifacts0 = artifacts(sources, javadoc, artifactTypes, subset).map { artifact =>
artifact.copy(attributes = Attributes())
}.distinct
val artifacts0 = artifacts(sources, javadoc, artifactTypes, subset).distinct

val logger =
if (verbosityLevel >= 0)
Expand Down Expand Up @@ -683,7 +687,7 @@ class Helper(
case _: FileError.NotFound => true
case _ => false
}
a.isOptional && notFound
a.optional && notFound
}

val artifactToFile = results.collect {
Expand Down Expand Up @@ -714,8 +718,8 @@ class Helper(
.mkString("\n")
}

val depToArtifacts: Map[Dependency, Vector[Artifact]] =
getDepArtifactsForClassifier(sources, javadoc, res).groupBy(_._1).mapValues(_.map(_._2).toVector)
val depToArtifacts: Map[Dependency, Vector[(Attributes, Artifact)]] =
getDepArtifactsForClassifier(sources, javadoc, res).groupBy(_._1).mapValues(_.map(t => (t._2, t._3)).toVector)


if (!jsonOutputFile.isEmpty) {
Expand All @@ -735,14 +739,15 @@ class Helper(
}
}).filter(_.isDefined).map(_.get).toMap

val artifacts: Seq[(Dependency, Artifact)] = res.dependencyArtifacts
val artifacts: Seq[(Dependency, Artifact)] = res.dependencyArtifacts().map {
case (dep, _, artifact) => (dep, artifact)
}

val jsonReq = JsonPrintRequirement(artifactToFile, depToArtifacts)
val roots = deps.toVector.map(JsonElem(_, artifacts, Option(jsonReq), res, printExclusions = verbosityLevel >= 1, excluded = false, colors = false, overrideClassifiers = overrideClassifiers(sources, javadoc)))
val jsonStr = JsonReport(
roots,
conflictResolutionForRoots,
overrideClassifiers(sources, javadoc)
conflictResolutionForRoots
)(
_.children,
_.reconciledVersionStr,
Expand All @@ -759,10 +764,10 @@ class Helper(
def fetch(
sources: Boolean,
javadoc: Boolean,
artifactTypes: Set[String],
artifactTypes: Set[Type],
subset: Set[Dependency] = null
): Seq[File] = {
fetchMap(sources,javadoc,artifactTypes,subset).values.toSeq
fetchMap(sources, javadoc, artifactTypes, subset).values.toSeq
}

def contextLoader = Thread.currentThread().getContextClassLoader
Expand All @@ -783,7 +788,7 @@ class Helper(

// FIXME That shouldn't be hard-coded this way...
// This whole class ought to be rewritten more cleanly.
val artifactTypes = Set("jar", "bundle")
val artifactTypes = core.Resolution.defaultTypes

val files0 = fetch(
sources = false,
Expand Down Expand Up @@ -867,9 +872,9 @@ class Helper(
module = dep.module
mainClass <- mainClasses.collectFirst {
case ((org, name), mainClass)
if org == module.organization && (
module.name == name ||
module.name.startsWith(name + "_") // Ignore cross version suffix
if org == module.organization.value && (
module.name.value == name ||
module.name.value.startsWith(name + "_") // Ignore cross version suffix
) =>
mainClass
}
Expand All @@ -880,7 +885,7 @@ class Helper(
module = dep.module
orgMainClasses = mainClasses.collect {
case ((org, name), mainClass)
if org == module.organization =>
if org == module.organization.value =>
mainClass
}.toSet
if orgMainClasses.size == 1
Expand Down
Expand Up @@ -4,7 +4,7 @@ import java.io.File
import java.net.URLClassLoader

import caseapp._
import coursier.Dependency
import coursier.{Dependency, moduleNameString, organizationString}
import coursier.cli.options.SparkSubmitOptions
import coursier.cli.spark.{SparkAssembly, Submit}

Expand All @@ -22,15 +22,15 @@ object SparkSubmit extends CaseApp[SparkSubmitOptions] {
def scalaSparkVersions(dependencies: Iterable[Dependency]): Either[String, (String, String)] = {

val sparkCoreMods = dependencies.collect {
case dep if dep.module.organization == "org.apache.spark" &&
(dep.module.name == "spark-core_2.10" || dep.module.name == "spark-core_2.11") =>
case dep if dep.module.organization == org"org.apache.spark" &&
(dep.module.name == name"spark-core_2.10" || dep.module.name == name"spark-core_2.11") =>
(dep.module, dep.version)
}

if (sparkCoreMods.isEmpty)
Left("Cannot find spark among dependencies")
else if (sparkCoreMods.size == 1) {
val scalaVersion = sparkCoreMods.head._1.name match {
val scalaVersion = sparkCoreMods.head._1.name.value match {
case "spark-core_2.10" => "2.10"
case "spark-core_2.11" => "2.11"
case _ => throw new Exception("Cannot happen")
Expand Down
@@ -1,9 +1,10 @@
package coursier.cli.options

import caseapp.{ HelpMessage => Help, ValueDescription => Value, ExtraName => Short, _ }
import caseapp.{ExtraName => Short, HelpMessage => Help, ValueDescription => Value, _}
import coursier.core.{Resolution, Type}

object ArtifactOptions {
def defaultArtifactTypes = Set("jar", "bundle", "test-jar")
def defaultArtifactTypes = Resolution.defaultTypes

implicit val parser = Parser[ArtifactOptions]
implicit val help = caseapp.core.help.Help[ArtifactOptions]
Expand All @@ -17,19 +18,21 @@ final case class ArtifactOptions(
@Help("Fetch artifacts even if the resolution is errored")
force: Boolean = false
) {
def artifactTypes(sources: Boolean, javadoc: Boolean) = {
def artifactTypes(sources: Boolean, javadoc: Boolean): Set[Type] = {

val types0 = artifactType
.flatMap(_.split(','))
.filter(_.nonEmpty)
.map(Type(_))
.toSet

if (types0.isEmpty) {
if (sources || javadoc)
Some("src").filter(_ => sources).toSet ++ Some("doc").filter(_ => javadoc)
Some(Type.source).filter(_ => sources).toSet ++ Some(Type.doc).filter(_ => javadoc)
else
ArtifactOptions.defaultArtifactTypes
} else if (types0("*"))
Set("*")
} else if (types0(Type("*")))
Set(Type("*"))
else
types0
}
Expand Down
@@ -1,8 +1,7 @@
package coursier.cli.options

import caseapp.{ HelpMessage => Help, ValueDescription => Value, ExtraName => Short, _ }

import coursier.core.ResolutionProcess
import caseapp.{ExtraName => Short, HelpMessage => Help, ValueDescription => Value, _}
import coursier.core.{Classifier, ResolutionProcess}

final case class CommonOptions(
@Help("Keep optional dependencies (Maven)")
Expand Down Expand Up @@ -109,7 +108,7 @@ final case class CommonOptions(

) {
val verbosityLevel = Tag.unwrap(verbose) - (if (quiet) 1 else 0)
lazy val classifier0 = classifier.flatMap(_.split(',')).filter(_.nonEmpty).toSet
lazy val classifier0 = classifier.flatMap(_.split(',')).filter(_.nonEmpty).map(Classifier(_)).toSet
}

object CommonOptions {
Expand Down
Expand Up @@ -68,7 +68,7 @@ final case class IsolatedLoaderOptions(
mod,
ver,
configuration = "runtime",
attributes = Attributes("", "")
attributes = Attributes()
)
}
}
Expand Down

0 comments on commit 4909c5e

Please sign in to comment.